Создает ли оператор присваивания по умолчанию утечку памяти при мелком копировании указателей?

Я новичок на этом сайте и в мире программирования. Поэтому, пожалуйста, будьте терпеливы со мной 🙂

Я прочитал о правиле трех и понял, как работает конструктор копирования и оператор присваивания.
Таким образом, я понял, что стандартные, предоставляемые C ++, предоставляют мелкую копию (или для каждого элемента) объектов.

Мой вопрос … если у класса есть указатель на член (который указывает на динамически выделенную память), оператор назначения по умолчанию будет копировать только адрес, содержащийся в указателе, из исходного объекта в указатель объекта, которому назначается , Но не приведет ли это к утечке памяти?
Например, следующий код:

class GCharacter //Game Character
{
private:
std::string name;
int capacity;   //the capacity of our tool array
int used;       //the nr of elements that we've actually used in that tool array
std::string* toolHolder; //string pointer that will be able to reference our ToolArray;

public:
static const int DEFAULT_CAPACITY = 5;
//Constructor
GCharacter(std::string n = "John", int cap = DEFAULT_CAPACITY)
:name(n), capacity(cap), used(0), toolHolder(new string[cap])
{
}
}

int main()
{         GCharacter gc1("BoB", 5);
GCharacter gc2("Terry", 5);
gc2 = gc1;
GCharacter gc3 = gc1;

return 0;
}

Итак, в этом коде при создании gc1 gc1.toolHolder содержит адрес некоторой динамически распределенной памяти из 5 строк. Скажем, адрес 125. После этого создается gc2, который динамически распределяет память для 5 строк, и, скажем, gc2.toolHolder содержит адрес 135.

Следующая строка кода вызывает оператор присваивания по умолчанию и предоставляет полную копию от каждого члена gc1 до gc2. Это означает, что теперь указатель gc2.toolHolder также содержит адрес 125, и мы больше не можем получить доступ к памяти по адресу 135. Таким образом, оператор присваивания по умолчанию в подобных ситуациях создает утечки памяти? … или я что-то не так понял ??

Кроме того, другой вопрос, в случае конструктора копирования по умолчанию, поскольку он вызывается только для объектов, которые еще не существуют, это означает, что gc3.toolHolder не получит возможность выделить новую память, скажем, по адресу 145? Он просто получит адрес, хранящийся в gc1.toolHolder?

Чтобы попытаться быть более конкретным … я спрашиваю, если это тот же случай, что и выше, за исключением того, что у нас просто есть оба указателя gc3.toolHolder и gc1.toolHolder, ссылающиеся на один и тот же адрес 125, без gc3.toolHolder динамического выделения нового память на 5 струн.

Короче говоря, когда мы создаем экземпляр класса с переменной-указателем, указывающей на динамически выделенную память, вызовет ли оператор присваивания по умолчанию утечку памяти? а конструктор копирования по умолчанию делит указатели на одну и ту же выделенную память?

Спасибо за ваше время!

2

Решение

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

~GCharacter() { delete[] toolHolder; }

Если вы добавите это, вы увидите вторую проблему, с которой вы столкнулись: сгенерированный по умолчанию copy-ctor и присваивание просто копируют / присваивают указатель, следовательно, когда у вас есть копия, а оригинал и копия выходят из области видимости, они будут и то и другое попробуйте удалить память. Это двойной бесплатный, конечно, гораздо большая проблема чем утечка памяти, так как это, скорее всего, повредит память.

Тем не менее, вы хотите добавить свой собственный copy-ctor и оператор присваивания и реализовать его правильно. В этом случае это означает выделить память для копии toolHolder, Вообще, читайте о Rule of Five когда реализовать какой набор методов для вашего класса.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]