Куча коррупции? В МОЕЙ динамической памяти?

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);
Другие вопросы по тегам