2016-06-13 4 views
1

Я новичок в C++, пытаясь следовать учебной серии, чтобы изучить язык, задача, выделенная для выделения памяти, - выделить память на 26 символов, а затем заполнить их алфавитом, abcde ... и т.д.Выделение памяти указателями

Я думал, что я знал, что решение, но столкнулся с этой ошибкой: Invalid address specified to RtlValidateHeap(00490000, 0049D9EC) та часть, которая бросает меня есть программа выполняется полностью, аз, но по-прежнему бросает эту ошибку

Вот мой код:

char c = 'a'; 
char *pChar = new char[26]; 

for (int i = 0; i < 26; i++, pChar++, c++) { 
    *pChar = c; 
    cout << *pChar << flush; 
} 

delete[] pChar; 

Извините если вопрос сформулирован плохо, я новичок как в C++, так и в stackoverflow.

+0

Почему вы не просто объявить 'обугленного strAlphabet [27];» переменная, и в вашем цикле 'for' обратный доступ к индексу с помощью' strAlphabet [i] = c; '? Затем установите последний (индекс 26, позиция 27 - '\ 0'). Таким образом, вы не беспокоитесь о указателях и распределении/освобождении памяти. Затем просто загрузите 'strAlphabet' один раз до cout после цикла? Или вы работаете над упражнением об использовании указателей? –

+3

@AndrewTruckle не проблема на этот раз, '* pChar' печатает только один символ, но важно отметить, что нужно знать. 'cout << pChar;' (обратите внимание на отсутствующий символ '*'), который переходит в неопределенное поведение. Что, вероятно, произойдет, так это то, что программа будет печатать до тех пор, пока не найдет нулевой символ или программа не выйдет из строя, но для компьютера будет так же хорошо расти, как и танец сальсы вокруг вашей комнаты. – user4581301

+1

@ user4581301 Да, я понял, что он сделал один символ. Наверное, я просто не буду писать задачу так, как она была представлена. –

ответ

5

Когда вы говорите delete[] pChar;, вы на самом деле пытаетесь удалить то, что на данный момент указывает pChar, что не то место, где первоначально было выделено.

Вкратце, когда вы выделяете что-то с new, он помещает некоторые данные о распределении (например, размер распределения, поэтому вам не нужно указывать delete[26] pChar;, как вы должны были, когда C++ был новым), как правило, слева от недавно выделенная память, и, вероятно, она интерпретирует написанные вами (алфавит) данные в качестве этой информации при попытке использовать ее для освобождения памяти, что, конечно же, не сработает.

Вы должны сохранить копию исходного указателя на память вы выделили вместо этого и использовать его для удаления, или, возможно, лучший вариант, использовать i и индексы для индексации с помощью арифметики указателей вместо как:

char c = 'a'; 
char *pChar = new char[26]; 

for (int i = 0; i < 26; i++, c++) { 
    pChar[i] = c; 
    cout << pChar[i] << flush; 
} 

delete[] pChar; 
+0

Спасибо, я создал * pStart указатель для хранения этой исходной ячейки памяти, и теперь она работает идеально, я буду принимать этот ответ, как только это позволит мне! –

+0

@WillScott: То, что вы действительно должны делать, это использовать 'std :: string' или, по крайней мере,' std :: vector'. Старайтесь держаться подальше от 'new []' и 'delete []' столько, сколько сможете, пусть STL сделает для вас работу. –

+0

@RemyLebeau Как было сказано ранее, единственная причина, по которой я использую новый и удалить, - это использовать распределение памяти по учебнику. –

2

Проблема заключается в том, что когда управление покидает петлю, pChar указывает на местоположение, расположенное за концом массива. Затем вы вызываете delete[] на этот указатель, который походит на то, что он разбивает шарик через неправильный дом.

1

Как уже упоминалось в других ответах, вы не можете позвонить по номеру delete[] по указателю, который вы изменили с момента вызова new []. Это неопределенное поведение.

delete [] необходимо передать точно такое же значение указателя, какое вы достигли при вызове new[].


И здесь самое простое решение проблемы, без необходимости менять pChar:

#include <iostream> 

int main() 
{   
    char c = 'a'; 
    char *pChar = new char[26]; 

    for (int i = 0; i < 26; ++i) { 
     pChar[i] = c; // access the character by index ... 
     std::cout << pChar[i] << std::flush; // access the character by index ... 
     // ++pChar; DON'T change the original pointer 
     ++c; 
    } 

    delete[] pChar; 
    return 0; 
} 

Live Demo

+0

Извините, но зачем это нужно? Принятый ответ уже включает это. – NathanOliver

Смежные вопросы