C++: Удалить структуру?

У меня есть структура, которая содержит указатели:

struct foo
{
    char* f;
    int* d;
    wchar* m;
}

У меня есть вектор общих указателей на эти структуры:

vector<shared_ptr<foo>> vec;

vec выделяется на стеке. Когда это передаст из объема в конце метода, его деструктор назовут. (Право?), Который в свою очередь назовет деструктор каждого элемента в векторе. (Право?) Делает вызов delete foo удалите просто указатели такой как foo.f, или это на самом деле освобождает память от "кучи"?

6
задан Nick Heiner 8 June 2010 в 21:11
поделиться

6 ответов

delete foo;

удалит память, выделенную для структуры foo, которая включает три указателя. Но память, на которую указывают сами указатели, будет удалена, только если вы реализуете деструктор, который явно удалит их.

15
ответ дан 8 December 2019 в 03:38
поделиться

Если у вас динамически выделен foo , например:

foo* f = new foo;

, то delete f уничтожит динамически выделенный объект foo , включая указатели, которые он содержит, но не ничего, на что указывают указатели, если они действительно указывают на динамически выделяемые объекты или массивы объектов.

Если вы назначили динамически размещаемый объект foo (то есть результат new foo ) для shared_ptr (при условии tr1 или boost), то когда последний shared_ptr , ссылающийся на этот объект, выходит за пределы области delete будет автоматически вызываться для указателя, первоначально возвращенного new foo . Вам не нужно делать это вручную.

Если ваш объект ( foo ) содержит указатели на динамически выделяемые объекты, которыми он владеет (поэтому необходимо освободить место в конце времени существования foo ), то настоятельно рекомендуется вы пишете деструктор, чтобы освободить эти объекты правильным способом (который будет зависеть от того, как они распределяются).

После того, как вы написали деструктор, вам нужно подумать, нужно ли вам писать конструктор копирования и оператор копирования. Поскольку вы используете вектор общих указателей, вы можете решить, что ваши объекты не следует копировать. В таком случае вы можете объявить их частными и не требовать реализации.

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

10
ответ дан 8 December 2019 в 03:38
поделиться

Удаляет только указатели.

1
ответ дан 8 December 2019 в 03:38
поделиться

Похоже, в вашем вопросе есть некоторая терминологическая путаница. Деструктор вектора вызовет деструкторы для элементов shared_ptr , которые, в свою очередь, будут внутренне выполнять delete для своих сохраненных указателей (при необходимости).

Вызов delete foo , где foo - указатель на struct foo , вызовет деструктор struct foo и затем освободит память занята * foo .

Деструктор приведенной выше struct foo абсолютно ничего не делает. Это банально. If не будет предпринимать никаких попыток освободить память, указанную struct foo :: f или любыми другими членами. Зачем это нужно? Он не знает и не может знать, следует ли освобождать эту память.

Фактически, поскольку struct foo :: ~ foo тривиален, компиляторы обычно даже не пытаются его вызвать.

1
ответ дан 8 December 2019 в 03:38
поделиться

Вы не вызываете delete f , где f - объект типа foo , если f выделен в стеке. Вы также не вызываете delete f для выделенного в куче объекта типа foo , если этот адрес хранится в общем указателе. shared_ptr objets вызовет для вас delete , когда будет освобождена последняя ссылка.

Так как ваш вектор хранит интеллектуальные указатели, они также выпадут из области видимости, когда ваш вектор выпадет из области видимости и будет вызван деструктор foo и соответствующая память будет освобождена. Однако память foo имеет размер только 3 указателя. Не то, что содержат эти указатели.

Если элементы foo выделены в куче, вам потребуется удалить их отдельно. Например, возможно, внутри деструктора foo, если память, на которую они указывают, не используется совместно между объектами.


Когда он выходит из области видимости в конце метода, вызывается его деструктор. (Верно?)

Верно.

Это, в свою очередь, вызовет деструктор каждого элемента вектора. (Верно?)

Верно. Деструктор умного указателя.

или действительно освобождает память из кучи?

Он вызывает деструктор интеллектуального указателя, если больше нет ссылок на этот указатель, то содержащийся в нем объект будет удален, а его память будет освобождена.

1
ответ дан 8 December 2019 в 03:38
поделиться

Когда [vec] выходит за пределы области видимости в конце метода, вызывается его деструктор. (Верно?)
Correct

Это, в свою очередь, вызовет деструктор каждого элемента в векторе. (Верно?)
Верно, это приведет к удалению элементов shared_ptr в контейнере, а если они последние, то и элементов, которыми они совместно пользуются.

Вызов delete foo ...?
Вы не можете удалить foo, это структура. Вы можете удалить экземпляр foo.
Вызов delete вызывает деструктор и освобождает память для структуры foo.

Удаляет ли деструктор foo только указатели, такие как foo :: f, или действительно освобождает память из кучи?
Это зависит от destructo, в этом случае у вас есть деструктор по умолчанию и так далее .. .
Нет. В следующем примере кода вы можете увидеть некоторые из причин, по которым деструктор по умолчанию, связанный с foo, не может автоматически очищать любые элементы, на которые ссылается указатель.

{
 char ca='a', *cb=new char;
 int *i = (int*)malloc(sizeof(int));
 foo a;
 shared_ptr<foo> b = new foo();
 a.f = &ca;
 a.d = i;
 b.f = cb;
}
0
ответ дан 8 December 2019 в 03:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: