Программа не выходит из-за удаления []

0

Таким образом, моя программа выполняется так, как ожидалось, и выводит правильный результат. Единственная проблема заключается в том, что после ее завершения он не выходит. Если я подожду еще несколько секунд, появится окно с сообщением "bignumbs.exe перестает работать". Вот код новой функции, которая, кажется, вызывает проблему.

void BigInt::u_basic_mult(const BigInt& n, int digs)
{
    const base_int* tptr = n.used > used ? n.data : data;
    const base_int* bptr = tptr == data ? n.data : data;
    const int tlen = tptr == data ? used : n.used;
    const int blen = bptr == data ? used : n.used;
    if(digs < 1)
    digs = tlen + blen + 1;
    base_int* new_data = new base_int[digs];
    for(int i = 0; i < digs; ++i)
    *new_data++ = 0;

    for(int i = 0; i < blen; ++i)
    {
    int stop_pt = MIN(tlen, digs - i);
    overflow_int carry = 0;
    overflow_int btmp = bptr[i];
    for(int j = 0; j < stop_pt; ++j)
    {
        overflow_int prod = btmp * tptr[j] + carry;
        carry = prod >> BASE_BITS;
        overflow_int sum = new_data[i + j] + carry + (prod & MAX_DIG);
        carry += sum >> BASE_BITS;
        new_data[i + j] = sum;
    }
    }
    //delete[] data; these two lines cause the error
   //data = new_data;
    used = digs;
    alloc = digs;
    strip_zeros();
}

Обратите внимание на две строки, которые я прокомментировал. Без них программа выполняет и заканчивает (хотя теперь результат неверен). Что это значит изменить значение указателя или удалить его, что может сделать мою программу этой странной ошибкой? Также я уверен, что данные действительны, так как я использую их в приведенном выше коде.

Также я компилирую с G++ через Netbeans.

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

BigInt::~BigInt()
{
    if(data) delete[] data;
}
  • 0
    вызов delete на null - это нормально, проверка не нужна.
  • 0
    Вы можете рассмотреть данные std::vector<base_int> data .
Теги:
memory-management

3 ответа

1
Лучший ответ
for(int i = 0; i < digs; ++i)
    *new_data++ = 0;

Этот код модифицирует где new_data указатель не указывает на, так что она больше не указывает на оригинальный массив при входе в последующий цикл, или сделать что - нибудь с ним по этому вопросу. Указатель, который вы передаете для delete[] должен указывать на тот же адрес памяти, что и new[].

Правильный способ ноль-инициализации массива состоит в том, чтобы сделать это вместо этого:

for(int i = 0; i < digs; ++i)
    new_data[i] = 0;

Или, избавитесь от цикла и просто используйте memset():

memset(new_data, 0, digs * sizeof(base_int));
1

Я понял. Мне удалось испортить мой указатель new_data.

 for(int i = 0; i < digs; ++i)
     *new_data++ = 0;

Я изменил это на это.

for(int i = 0; i < digs; ++i)
     new_data[i] = 0;
1

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

Я не могу дать вам более конкретные рекомендации по этой конкретной программе, потому что вы не показываете нам, где указывается указатель с именем data.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню