Концепция динамического массива с контейнерным классом? - PullRequest
0 голосов
/ 13 марта 2012

Я просто не понимаю, что такое динамический массив с классом контейнера. Вот пример того, как я это делаю.

Класс контейнера:

class Container{
private:
    int n, current;
    Class *C;
public:
    Container(): C(NULL), n(0), current(0){}
    void expandC(int ammount){
      Class *NewClass= new Class[ammount];
      for (int i = 0; i < n; i++)
        NewClass[i] = C[i];
        delete []C;
        C = NewClass;
        n = ammount;
    }

};

Почему яполучить ошибку в строке delete[] C?

РЕДАКТИРОВАТЬ: Если поймано суть правила трех, это означает, что вы должны определить конструктор копирования оператор присваивания или деструктор.В моем случае наиболее важным, вероятно, является конструктор копирования.Вот как я понял, как они должны быть определены в моем случае:

Container(): C(NULL), n(0), current(0){}
Container(int N, vector<string> a){
    C = new Class[N];
    for(int i = 0; i<n; i++){C->setA(a[i]);}
    n=N;
}
~Container(){ delete [] C;}

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

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

Unhandled exception at 0x53f0edfc (msvcr90d.dll) in dinamicTest.exe: 0xC0000005: Access violation writing location 0xabababab.

Вот запрашиваемая начальная полная версия этой программы http://pastebin.com/djTz36Tu

Ответы [ 2 ]

3 голосов
/ 13 марта 2012

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

Обратите внимание, что у вас есть член-указатель C в вашем классе Container, этот член-указатель указывает на динамически выделенную память. Теперь подумайте о сценарии, в котором ваш код должен создавать копии класса Container. Поскольку вы не предоставляете перегруженный конструктор копирования, будет использоваться созданный компилятором неявный конструктор копирования. Элемент указателя будет скопирован в только что созданный объект. Когда это происходит, указатели членов объекта из нескольких указателей указывают на одну и ту же динамическую память, когда один из них получает delete d, другой становится висящим указателем и вызывает проблему.

0 голосов
/ 14 марта 2012

Проблема заключается в addC.Рассмотрим эти две строки:

      expandC(n+1);
      C[n].setA(name);

Этот появляется для увеличения размера динамически распределяемого массива, а затем сохраняет значение в последней записи в массиве.Конечно, если массив имеет размер n+1 записей, то окончательная запись индексируется как n.

Но , n не является локальной переменной для addC.n является членом класса и устанавливается как побочный эффект операции expandC.

Рассмотрим следующие аннотированные строки:

    // n starts out as 10:
    expandC(n+1);  // calls expandC(11), of course
                   // but expandC sets n to 11!
    // n is now 11
    C[n].setA(name);  // C has 11 entries, but n is 11: BOOM!

Вы можете решить эту проблемутаким образом:

    void addC(string name){
      expandC(n+1);
      C[n-1].setA(name);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...