Я однажды задал этот вопрос, и после нескольких часов исследования я думаю, что ответы не подходят и не решают мою проблему. Пожалуйста, проверьте этот код:

 #include <iostream>
using namespace std;

class Test
{
public:
    Test();
    Test(int);
    ~Test();
    friend Test Problem();
    int get_a ();
private:
    int* a;
};

Test::Test(int x)
{
    a = new int[1];
    *a = x;
}

Test::~Test()
{
    delete [] a;
}

Test Problem()
{
    Test doomed(1);
    int* doomed_too = new int[1];
    *doomed_too = 99;
    doomed.a = doomed_too;
    return doomed;
}

int Test::get_a()
{
    return *a;
}

int main()
{
    Test Sniffer = Problem();
    if (Sniffer.get_a() == 99) cout << "You saved me! Thanks!";
    return 0;
}

Да, я знаю, что обреченный объект будет уничтожен перед возвратом в объект Sniffer, поэтому Sniffer получит случайное значение из освобожденной памяти кучи. У меня вопрос - как спасти «жизнь» обреченного объекта? Можете ли вы предоставить рабочий код / ​​"исправление"?

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

Буду рад, если вы сможете сначала протестировать свое решение (прежде чем отвечать).

Я провел много исследований по этой теме, и меня позабавило, что во всех лекциях и примерах всегда используются нединамические частные члены или, если они используют в своих примерах динамические частные члены, они всегда «пропускают», чтобы показать перегрузку оператора + или перегрузку оператора * (просто Примеры).

Как мы можем сделать оператор + перегрузку общедоступной функции-члена данного класса, если тот же самый класс обладает динамическим частным членом, например int * n?

-2
mirosoft 8 Апр 2014 в 23:30

2 ответа

Лучший ответ

Вы должны реализовать конструктор копирования:

Test::Test(const Test& other)
{
  this->a = new int;
  *this->a = *other.a;
}

Некоторые другие проблемы:

  • зачем вы создаете a = new int[1]? это должно быть просто a = new int

  • если вам действительно нужно a = new int[1] соответствующее удаление для массивы в C ++ обычно должны быть delete [] a.

В качестве альтернативы вы можете использовать интеллектуальный указатель (std::tr1::shared_ptr или аналогичный, в зависимости от вашего компилятора), см. http://en.cppreference.com/w/cpp/memory/shared_ptr

3
Andrei Bozantan 8 Апр 2014 в 20:30

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

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

0
Community 23 Май 2017 в 12:28