У меня проблема с вызовом удаления внутри функций. Когда я выделяю память, используя новую внутреннюю функцию, это, кажется, работает, но удаление ранее выделенной памяти вызывает выброс std :: bad_alloc. Это вообще возможно, или я могу только освободить память под «а» изнутри main?
#include <iostream>
using namespace std;
int size = 5;
void alloc (int* t, char**& a) {
t = new int [size];
a = new char* [size];
for (int i = 0; i < size; ++i)
a[i] = new char [size];
cout << "allocated\n";
}
void realloc (char**& a) {
for(int i = 0; i < size; ++i)
delete [] a[i];
delete [] a;
cout << "deleted\n";
a = new char* [size];
for (int i = 0; i < size+5; ++i)
a[i] = new char [size+5];
cout << "allocated\n";
}
void fillArray (char** a) {
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
a[i][j] = '.';
}
}
}
void printArray (char** a) {
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
cout << a[i][j];
}
cout << endl;
}
}
int main() {
int* t;
char** a;
alloc(t, a);
fillArray(a);
printArray(a);
size+=5;
realloc(a);
fillArray(a);
printArray(a);
}
Ты можешь позвонить delete[]
откуда угодно. Ваши проблемы гораздо прозаичнее. У вас просто есть дефект в вашем коде.
Вы выделяете массив длины size
, Тогда вы увеличиваете size
, Затем вы делаете это:
for(int i = 0; i < size; ++i)
delete [] a[i];
И потому что вы увеличили size
уже твой цикл заканчивается a
, Вам нужно использовать то же значение для size
как было использовано при выделении массива.
Чтобы быть совершенно ясным, следующий поток выполнения:
size
присваивается значение 5
,a
выделяется с длиной 5
,size
увеличивается до значения 10
,for
цикл от 0
в size-1
, то есть 0
в 9
и позвоните delete[] a[i]
,Ясно, что итерации 5
в 9
включительно получают доступ к элементам a
которые не были выделены. И это неопределенное поведение, и так далее.
Вы можете исправить это, передав новый размер realloc
функция в качестве параметра. Что-то вроде этого:
void realloc (char**& a, size_t newsize) {
for(int i = 0; i < size; ++i)
delete [] a[i];
delete [] a;
size = newsize;
a = new char* [size];
for (int i = 0; i < size; ++i)
a[i] = new char [size];
}
Очевидно, вы не изменили бы size
вне этой функции. Вы бы назвали функцию так:
realloc(a, size+5);
Пройдя немного дальше, вы можете выбрать обработку распределений следующим образом:
size_t size = 5;
void alloc(char**& a, size_t newsize) {
size = newsize;
a = new char*[size];
for (int i = 0; i < size; ++i)
a[i] = new char[size];
}
void realloc(char**& a, size_t newsize) {
for(int i = 0; i < size; ++i)
delete[] a[i];
delete[] a;
alloc(a, size+5);
}
Все это говорит, и, будучи совершенно откровенным, вся ваша программа — катастрофа в процессе становления. Есть много других ошибок, которые я не рассмотрел в этом ответе. Используйте стандартные контейнеры, такие как std::vector
а также std::string
, Стандартные контейнеры будут обрабатывать детали выделения памяти и будут делать это правильно.
Других решений пока нет …