Куча коррупции? В МОЕЙ динамической памяти?
void longcatislong(int* cat, int &size, int &looong)
{
int* longcat = new int[looong*2];
for(int i = 0; i < size; i = i + 1)
longcat[i] = cat[i];
delete [] cat;
cat = longcat;
looong = looong * 2;
}
Суп, ребята. Я /r/ прилагаю некоторую помощь в решении этой проблемы с моим кодом. Очевидно, что-то в моем C++ коде вызвало ошибку повреждения кучи и что-то delete[] cat
, cat - это динамический массив целых чисел, созданный с помощью оператора new и указателя. Почему же тогда, когда я использую массив delete, вся программа решает быть раздавленной паровым катком и говорит, что у меня повреждена куча. Мне 12 и что это?
3 ответа
Вы проходите cat
указатель по значению, поэтому любые изменения, которые вы делаете внутри функции, не отражаются снаружи. Вам нужно передать указатель по ссылке, как int*& cat
,
cat
не возвращается вызывающей стороне этой функции. Вы изменяете только локальную копию, когда выполняете cat = longcat
,
Это означает, что параметр, который вы передали этой функции, по-прежнему указывает на старый адрес, который вы очень неудобно удалили.
Либо передайте его в качестве ссылки, либо сделайте старый трюк с двойным указателем C и передайте его адрес.
Вы также можете убедиться, что при первом вызове cat
имеет действительное значение и size
а также looong
совместимы (looong * 2 >= size
) чтобы ты не испортил память.
Посмотрите на следующий код, который иллюстрирует вашу проблему:
#include <iostream>
void longcatislong1(int* cat, int &size, int &looong)
{
int* longcat = new int[looong*2];
for(int i = 0; i < size; i = i + 1)
longcat[i] = cat[i];
delete [] cat;
cat = longcat;
looong = looong * 2;
}
void longcatislong2(int*& cat, int &size, int &looong)
{
int* longcat = new int[looong*2];
for(int i = 0; i < size; i = i + 1)
longcat[i] = cat[i];
delete [] cat;
cat = longcat;
looong = looong * 2;
}
int main (void) {
int sz = 0;
int lng = 10;
int *ct = 0;
std::cout << ct << std::endl;
longcatislong1 (ct, sz, lng);
std::cout << ct << std::endl;
longcatislong2 (ct, sz, lng);
std::cout << ct << std::endl;
return 0;
}
Его вывод:
0
0
0x9c83060
это означает, что longcatislong1
вызов не был успешно установлен ct
по возвращении. longcatislong2
Функция, которая передает указатель в качестве ссылки, устанавливает ct
правильно.
Допустим, у вас есть действительный указатель на 0xf0000000
, Когда вы вызываете свою исходную функцию, выделяется новый блок памяти, данные копируются и старый блок удаляется.
Но ct
переменная по-прежнему указывает на старый блок.
При следующем вызове функции или даже при разыменовании ct
в другом месте вас ждет мир боли, обычно называемый неопределенным поведением.
Делая первый параметр ссылочным типом, изменения, внесенные в функцию, отражаются обратно в переданной переменной.
Вы должны удалить int* cat через int** cat в аргументах функции, а затем заменить все вставки cat в теле функции на * cat даже в месте размещения cat[i].
void longcatislong(int** cat, int &size, int &looong)
{
int* longcat = new int[looong*2];
for(int i = 0; i < size; i = i + 1)
longcat[i] = *cat[i];
delete [] *cat;
*cat = longcat;
looong = looong * 2;
}
А потом, когда вы вызываете функцию, вызывайте ее так:
longcatislong(&cat, size, looong);