Область действия объекта в массиве - PullRequest
0 голосов
/ 24 августа 2011

Предположим, у вас есть массив объектов в C ++, и вы удаляете один из объектов из массива.Когда вызывается деструктор этого объекта?Поскольку в C ++ нет автоматического сбора мусора, было бы странно, если бы деструктор вызывался сразу после удаления из массива.Но остается ли объект выделенным, пока массив не выйдет из области видимости?Похоже, это приведет к утечкам памяти.

Редактировать:

Вместо "удалить", как насчет установки одного из элементов массива в другой объект.

Кроме того, что происходит , когда элемент удаляется из std::vector?

Ответы [ 4 ]

2 голосов
/ 24 августа 2011

Вы не можете «удалить один из объектов из массива». Массивы имеют фиксированный размер. Все содержимое создается во время создания и уничтожения массива при уничтожении самого массива.

Если вы просто назначаете новое значение элементу массива, то вы вызываете оператор = объекта, и он ведет себя не иначе, как если бы вы имели простую автономную переменную и присвоили ей новое значение. Никакие объекты не обязательно построены или разрушены. Если есть какой-либо новый объект, это временный объект, который генерирует компилятор для правой части оператора присваивания. После завершения оператора временный объект уничтожается. Объект в массиве остается без изменений.

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

1 голос
/ 24 августа 2011

Когда вы объявляете массив C ++, он создает все объекты в стеке и остается там до тех пор, пока сам массив не будет удален:

std::string ArrayOfStrings[10]; //There are now ten strings here

Объекты не могут быть «удалены» из этоговид массива.Когда ArrayOfStrings выходит из области видимости, он автоматически удаляет все строки в массиве.Если вы редактируете объект в этом массиве, сам этот объект изменяется.Вы действительно изменили саму строку, а не какой-либо указатель или ссылку.

Если у вас есть массив указателей, то C ++ создает все указатели, но вы должны сами управлять тем, на что они указывают:

std::string* ArrayOfPointersToStrings[10];

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

Если у вас есть std :: vector, C ++ создает только некоторые объекты в зависимости от того, как вы его создаете:

std::vector<std::string> VectorOfStrings(10);

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

Чтобы уточнить комментарии:

char *myLiteral = "APPLE";
//"APPLE" is an immutable string, myLiteral points at it.
std::string s= myLiteral; 
std::string t = myLiteral;
//s and t each makes a _seperate_ _mutable_ copy of "APPLE"
s[3] = '?'; 
//s is now "APP?E", because we just changed the L.  NO COPY WAS DONE. 
std::cout << t[3];
//displays "L", because t's copy was never changed.
0 голосов
/ 24 августа 2011

Вы не можете удалять объекты из ванильного массива C ++. Когда вы объявляете массив определенного размера, независимо от того, находится ли он в стеке или куче, предполагая, что выделение прошло успешно, выделяется достаточно памяти для создания N объектов этого типа, и они создаются с использованием любого подходящего конструктора.

Использование оператора присваивания для копирования содержимого RHS на объект в массиве, как правило, ничего не делает с объектом на RHS. Память в массиве просто перезаписывается. Никакие новые объекты не создаются и не удаляются (если вы не сделаете что-то вроде obj1 = obj2 = obj3, представляющего собой «черную банку червей» ...)

0 голосов
/ 24 августа 2011

Для стандартного контейнера, такого как std::vector, к моменту завершения метода удаления объект был уничтожен.

Для массива "c-style" сам объект будет существоватьтак долго, как если бы его не было в массиве.

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

...