Если есть объект, давайте его назовем o
и два массива typeo *a,*b;
если я назначу o
в оба массива a
и массив b
затем delete[] b
что произойдет, если я попытаюсь получить доступ к o или o в a? Например:
struct name{int a;}
name *a = new name[1];
name *b = new name[1];
name o;
a[0] = o;
b[0] = o;
delete[] b;
a[0]; // what happens here?
В примере нет проблем. a[0]
а также b[0]
разные объекты в разных местах памяти, и уничтожение одного из них не влияет на другой.
new
красная сельдь; следующий код работает так же:
name o;
name a = o;
{
name b = o;
}
a;
name
имеет семантика значения, то есть копирование его по значению создает полностью отличную копию. Встроенные типы, такие как int
у всех тоже есть ценностная семантика.
Этот код будет сталкиваться только с проблемами, если o
не имел семантики значения; например, если он содержит дескриптор ресурса и не содержит код-конструктор копирования и код оператора присваивания для дублирования дескриптора ресурса.
Потом копирование o
будет делать два объекта с одинаковым дескриптором на этом ресурсе, и если o
деструктор освобождает ресурс, который он оставил бы висящую копию.
Чтобы избежать этих проблем, обычно рекомендуется, чтобы все ваши классы имели семантику значений. Если у класса есть дескриптор для ресурса, который не дублируется, то класс должен иметь свой конструктор копирования и оператор присваивания отключенным, чтобы предотвратить случайные копии. Фактически дескриптор ресурса должен храниться в классе, предназначенном для дескрипторов ресурса.
Это иногда называют «правилом трех» (или C ++ 11, «правилом пяти» или «правилом нуля»).
Если вы просто определите int a[1]
Вы не выделяете память в куче, поэтому нет необходимости удалять.
В противном случае, если вы создаете массив следующим образом:
int *a= new int[1]
,
Вы должны удалить как
delete [] a;
Рассматривая оба вышеупомянутых сценария, вы можете безопасно обращаться к `a ‘после удаления b, если вы выделили память для b и a.