LINUX.ORG.RU

C++11 и управление памятью

 , ,


0

8

Прочитал недавно о смарт-поинтерах в C++11. Можно ли считать это полноценной заменой GC используемых другими языками программирования, такими как Java/C#? Какие современные компиляторы полноценно поддерживают C++11? Есть ли полноценная поддержка C++14?

★★★★★
Ответ на: комментарий от vertexua

миллиард операций operator->() от shared_ptr медленнее на несколько порядков чем тот же оператор от unique_ptr

Код в студию

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

Просто for-loop по long счетчику до миллиарда. В теле цикла голый вызов obj->Inc(), который увеличивает счетчик внутри класса.

vertexua ★★★★★
()
Ответ на: комментарий от bbk123

Почему все говорящии о кольцевых ссылках забывают о weak_ptr?

Мне интереснее зачем вы отвечаете на то что даже не прочитали, а ведь я о weak_ptr явно упомянул и не один раз. В качестве домашнего задания вам - придумать задачу где есть кольцевые ссылки, но weak_ptr применить нельзя.

slovazap ★★★★★
()
Ответ на: комментарий от hlamotron

Убирает? Да.

Нет. shared_ptr просто при своем разрушении уменьшает счетчик ссылок на объект и вызывает некоторый объект-функцию, если счетчик стал 0.

Где здесь, например, сборка мусора?

auto f = fopen("a.tmp", "r");
if (f) {
    shared_ptr<FILE> fp(f, fclose);
    // ...
}

Что? Мусор.

Нет. Следим за счетчиком использования некоторого ресурса и обрабатываем ситуацию уничтожения последней ссылки.

Или выделенная память, про которую все забыли - не есть мусор?

GC работает с памятью. shared_ptr - с любыми ресурсами.

forCe
()
Последнее исправление: forCe (всего исправлений: 1)
Ответ на: комментарий от slovazap

Вот ты и расскажи про кольцевые ссылки, в которых weak_ptr нельзя. Зачем загадками разговаривать?

bbk123 ★★★★★
() автор топика
Последнее исправление: bbk123 (всего исправлений: 1)
Ответ на: комментарий от bbk123

В целом это можно назвать GC. C++ позволяет устроить месиво GC и не-GC одновременно )

hlamotron
()
Ответ на: комментарий от forCe

GC работает с garbage. Он её collect. То, что вы стали понимать под garbage именно память - к реальности мало относится. В вашем примере вполне себе garbage в виде выкинутого на помойку (= всеми забытого) ресурса в виде файла.

hlamotron
()
Ответ на: комментарий от hlamotron

То, что вы стали понимать под garbage именно память

Это не я

In computer science, garbage collection (GC) is a form of automatic memory management. The garbage collector, or just collector, attempts to reclaim garbage, or memory occupied by objects that are no longer in use by the program. Garbage collection was invented by John McCarthy around 1959 to abstract away manual memory management in Lisp.[1][2]

к реальности мало относится.

А мне кажется, что к реальности относятся мало именно ваши рассуждения.

forCe
()
Ответ на: комментарий от hlamotron

Код вам не поможет, вам понадобится

Оракул в треде! :D

Manhunt ★★★★★
()
Последнее исправление: Manhunt (всего исправлений: 1)
Ответ на: комментарий от vertexua

А лучше просто скажи какую используешь стандартную библиотеку. У меня в clang/libc++ доступ через обычный указатель, unique_ptr и shared_ptr работает одинаково быстро.

slovazap ★★★★★
()
Ответ на: комментарий от hlamotron

Возможно поможет потому что с вероятностью 99% у нас у обоих GCC/Clang на линуксе на Intel/AMD процессоре. А вот если результат бенчмарка не совпадет, тогда будем решать уже эту проблему.

vertexua ★★★★★
()
Ответ на: комментарий от forCe

А мне кажется, что к реальности относятся мало именно ваши рассуждения.

Мои рассуждения вполне логичны, а нелогично то, что какой-то дядя назвал мусором именно память (а не другие ресурсы) и вы этого дядю повторяете. Думайте своей головой, а не головой автора понятия. Этак завтра изобретатель какого-нибудь нового материала заявит, что это стекло. Не будет же это означать, что он изобрёл стекло )

hlamotron
()
Ответ на: комментарий от vertexua

В качестве домашнего задания вам - придумать задачу где есть кольцевые ссылки

Ну если даже с этим проблемы, то дальше общаться не о чем.

slovazap ★★★★★
()
Ответ на: комментарий от arturpub

Невозможность освободить участок памяти по недосмотру программиста

От недосмотров программиста слабые ссылки не спасают.

tailgunner ★★★★★
()
Ответ на: комментарий от vertexua

Сколько авторов библиотек и реализаций библиотек, столько и тараканов. Библиотека и компилятор - это такая же софтина с багами и нелогичными решениями, как многие другие софтины ) Выдерите код shared_ptr и код unique_ptr и будет самый точный ответ )

hlamotron
()
Ответ на: комментарий от slovazap

Ну я к тому что просят

Придумай задачу где надо разбить себе лоб, но можно и не разбивать

Есть конечно двусвязные списки или кривые связи у бизнес-обьектов, но часто можно без этого

vertexua ★★★★★
()
Ответ на: комментарий от bbk123

Вот ты и расскажи про кольцевые ссылки, в которых weak_ptr нельзя. Зачем загадками разговаривать?

Какой смысл рассказывать, если вы это не будете читать?

slovazap ★★★★★
()
Ответ на: комментарий от vertexua

Да, набрал. Только другой, потому что тот clang свёртывает в константу.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

Ну если даже с этим проблемы, то дальше общаться не о чем.

Если твоя и vertexua цель - заболтать тему совместным троллингом, то общаться действительно не о чем.

bbk123 ★★★★★
() автор топика
Ответ на: комментарий от hlamotron

Мои рассуждения вполне логичны

В вопросах терминологии логика мало чем помогает.

forCe
()
Ответ на: комментарий от forCe

Нет. shared_ptr просто при своем разрушении уменьшает счетчик ссылок на объект и вызывает некоторый объект-функцию, если счетчик стал 0.

Ну засунь в shared_ptr буфер с деструктором, который освобождает память буфера и будет тебе мега-строгое следование терминологии и мусор будет убираться.

hlamotron
()
Ответ на: комментарий от slovazap

Какой смысл рассказывать, если вы это не будете читать?

Да ты просто пророк. Какой смысл делать громкие заявления о кольцевых ссылках, умалчивая их суть. Чтобы потролить?

bbk123 ★★★★★
() автор топика
Ответ на: комментарий от slovazap

Вопрос в банальном уважении к собеседнику.

Вопросы уважения - это на восток-дело-тонкое, тут серьёзные мужики обсуждают факты. Если заниматься вопросами уважения, то кому-то может показаться, что его не уважают по факту спора с ним и опровержения его утверждений, порочат его репутацию-как-эксперта перед посетителями.

hlamotron
()
Ответ на: комментарий от hlamotron

Не будет. Т.к. во-первых, shared_ptr не потеряет возможность работать с разными ресурсами, а во-вторых, даже если закрыть на все отличия глаза, это довольно убогая стратегия «сборки», она даже детектора циклов не имеет. А вот как универсальный механизм для работы с множеством ссылок на ресурс RC вполне годен.

forCe
()
Последнее исправление: forCe (всего исправлений: 1)
Ответ на: комментарий от vertexua

Тащемта:

#include <iostream>
#include <chrono>
#include <memory>
#include <string>

class Counter {
private:
    volatile unsigned long value = 0;

public:
    void Inc() {
        value++;
    }

    unsigned long Get() {
        return value;
    }
};

int main(int argc, char**argv) {
    if (argc < 2) {
        std::cerr << "Usage: " << argv[0] << " iterations" << std::endl;
        return 1;
    }

    unsigned long nloops = std::stoul(argv[1]);

    Counter val;

    Counter *pptr = &val;
    std::unique_ptr<Counter> uptr { std::make_unique<Counter>() };
    std::shared_ptr<Counter> sptr { std::make_shared<Counter>() };

    auto t1 = std::chrono::steady_clock::now();
    for (unsigned long i = 0; i < nloops; i++)
        pptr->Inc();
    auto t2 = std::chrono::steady_clock::now();
    for (unsigned long i = 0; i < nloops; i++)
        uptr->Inc();
    auto t3 = std::chrono::steady_clock::now();
    for (unsigned long i = 0; i < nloops; i++)
        sptr->Inc();
    auto t4 = std::chrono::steady_clock::now();

    std::cerr << "   Pointer: " << pptr->Get() << " " << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() << " ms" << std::endl;
    std::cerr << "unique_ptr: " << uptr->Get() << " " << std::chrono::duration_cast<std::chrono::milliseconds>(t3 - t2).count() << " ms" << std::endl;
    std::cerr << "shared_ptr: " << sptr->Get() << " " << std::chrono::duration_cast<std::chrono::milliseconds>(t4 - t3).count() << " ms" << std::endl;

    return 0;
}
% c++ -O2 -std=c++1y 1.cc && ./a.out 1000000000
   Pointer: 1000000000 2348 ms
unique_ptr: 1000000000 2358 ms
shared_ptr: 1000000000 2251 ms

И, как очевидно,

.LBB0_16:                               # %.lr.ph48
                                        # =>This Inner Loop Header: Depth=1
    incq    -104(%rbp)
    decq    %rcx
    jne .LBB0_16
...
.LBB0_19:                               # %.lr.ph44
                                        # =>This Inner Loop Header: Depth=1
    incq    (%r14)
    decq    %rax
    jne .LBB0_19
...
.LBB0_21:                               # =>This Inner Loop Header: Depth=1
    incq    (%r13)
    decq    %rbx
    jne .LBB0_21
slovazap ★★★★★
()
Ответ на: комментарий от bbk123

Ты не плач, главное. Не хочешь сам думать, так и быть.

Дерево в котором у детей есть указатели на родителей - случай где можно применить weak_ptr. Произвольный граф - где нельзя. Просто же?

slovazap ★★★★★
()
Ответ на: комментарий от anonymous

То выходит, что это паттерн Object Pool

Разве в Object Pool объекты создаются и удаляются?

bbk123 ★★★★★
() автор топика
Ответ на: комментарий от forCe

Не потеряет и ладно, стратегия убогая, но сборка мусора, в значении «ненужная память» реализована.

hlamotron
()
Ответ на: комментарий от vertexua

операций operator->() от shared_ptr медленнее на несколько порядков чем тот же оператор от unique_ptr.

Точно каких-то debug-проверок нет? Ибо atomic_read тебе как раз и даст очень нехилое просаживание из-за блокировок межпроцессорной шины. Выложи код shared_ptr твоей реализации.

Pavval ★★★★★
()
Ответ на: комментарий от bbk123

Потому что ты не знаешь что сделать weak, все ссылки равнозначны, а кольцо может возникнуть разными путями.

slovazap ★★★★★
()
Ответ на: комментарий от vertexua
$ clang -v
clang version 3.5.0 (tags/RELEASE_350/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
Selected GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3
$ ldd --version
ldd (Gentoo 2.21-r1 p5) 2.21       # версия libc
...
vertexua ★★★★★
()

Нет, нельзя. GCC/Clang последних версий. С clang и libc++ вроде бы есть, за gcc/libstdc++ не скажу, но вроде бы тоже присутствует.
Да и в C++ GC не нужен, просто потому что вся прелесть и гибкость (А так же боль и страдания) С++ заключаются в полностью ручном управлении всем и вся. Если тебя это не устраивает, то зачем тебе С++?

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.