2017-01-27 10 views
0

Привет Я новичок в указателях и динамической памяти. Предполагается, что программа представляет собой стек на основе массива. Мне нужна помощь при ошибке, возникающей при попытке выделить память переменной-указателю, которая называется _pArr в .h-файле. Когда я пытаюсь создать новый массив с new double[], я получаю сообщение об ошибке «нечитаемой памяти» при отладке кода. В приведенном ниже коде я создал новый массив в .cpp-файле, а затем скопировал его в указатель _pArr, но я все равно получаю ту же ошибку.Непрочитанная память при создании массива указателей в C++

class CStack{ 
public: 
    Stack(void); 
    ~Stack(void); 
    . 
    . 
    . 
private: 
    int _capacity=NULL; 
    int _size=0; 
    double* _pArr; 
} 



CStack::CStack(void) 
{ 
    if (_capacity == 0){ 
     _capacity = 10; 
    } 
    else{ 
     _capacity = _capacity * 2; 
    } 
    double* arr; 
    arr = new double [_capacity] 

    _pArr=arr; 

    delete[] arr; 
} 

Почему эта ошибка возникает и как я могу ее исправить?

+0

Что такое 'arr' и почему вы удаляете его в конструкторе? Кроме того, это имя класса 'Stack' или' CStack'? – Barmar

+0

В чем смысл теста 'if (_capacity == 0)'? Так как это вновь созданный стек, а объявление класса инициализирует его '0', оно всегда будет' 0'. – Barmar

+0

Отключить тему, но не использовать 'NULL' для' int'. –

ответ

2

Вот что ваш код делает в конструкторе:

// Allocate memory for an array and set arr to point to that array. 
double* arr; 
arr = new double [_capacity] 

// Set _pArr to point to the same array. 
_pArr=arr; 

// Delete the array that arr and _pArr point to. If you 
// deference _pArr after this, bad things will happen. 
delete[] arr; 

Таким образом, вы не должны удалить массив сразу после выделенного его. (Там также отсутствует пропущенная точка с запятой.) Избавиться от этого, скорее всего, исправить вашу проблему, но тогда вам нужно удалить массив в деструкторе класса. И если вы должны использовать new[]/delete[], было бы гораздо легче сделать это в один шаг, а не создавать бесполезное временную переменную:

CStack::CStack(void) 
{ 
    if (_capacity == 0){ 
     _capacity = 10; 
    } 
    else{ 
     _capacity = _capacity * 2; 
    } 

    _pArr = new double [_capacity]; 
} 

CStack::~CStack(void) 
{ 
    delete[] _pArr; 
} 

неродственных на ваш вопрос, но это код, который удваивает _capacity Безразлично» t делать что-нибудь полезное, так как при вызове конструктора емкость всегда будет равна нулю. Если вы планируете расширять существующий CStack, вам нужно будет поместить его в метод, и вам нужно будет беспокоиться о создании нового массива для стека, копировании содержимого старого в новый, а затем удалении Старый.