2013-12-21 2 views
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 data'. – Jarod42

ответ

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, вы должны удалить его, используя форму массива delete. Если вы смешиваете и сопоставляете массив и формы без массива, вы получите такие сбои. Вы также никогда не должны удалять то, что не было назначено новым, и вы никогда не должны удалять одно и то же дважды.

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

1

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

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

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

for(int i = 0; i < digs; ++i) 
    new_data[i] = 0; 
Смежные вопросы