Почему я не могу освободить динамическую память? - PullRequest
0 голосов
/ 05 ноября 2011

EDIT

Нашел ответ. Это логическая ошибка, расположенная на

if(carry == 0 && index < 0)
    exit = true;

Поскольку каждый сегмент начинается с 18 цифр (отсюда index = 17; прямо перед циклом while), когда значение shift меньше значения, которое код будет продолжать записывать после answer[0]. Я исправил это, добавив дополнительное условие для отключения флага выхода.

Извините за путаницу.

ОРИГИНАЛЬНЫЙ ВОПРОС

Вот функция, которую я написал для умножения двух целых чисел в формате массивов символов, где каждая ячейка представляет одно десятичное число (например, 1234 будет «1234+»).

char* multichar(char* one, char* two)
{
    // one has m digits, two has n digits
    int m = char_size(one) - 1;
    int n = char_size(two) - 1;
    int m_seg = m / 9 + 1;
    int n_seg = n / 9 + 1;
    int m_head = m % 9;
    int n_head = n % 9;
    int index, shift;
    bool exit = false, m_flag = true, n_flag = true;
    _int64 product, alpha, bravo;
    char carry = 0, sum;
    char temp[18];
    char* answer = new char[m + n + 1];
    memset(answer, 0, m + n + 1);
    if(m_head == 0)
    {
        m_seg--;
        m_flag = false;
    }
    if(n_head == 0)
    {
        n_seg--;
        n_flag = false;
    }

    for(int i = n_seg - 1; i > -1; i--)
    {
        for(int j = m_seg - 1; j > -1; j--)
        {
            shift = m + n - (m_seg + n_seg - i - j) * 9 + 17;
            if(i == 0 && n_head != 0)
                bravo = segtoint(two, 0, n_head);
            else
                bravo = segtoint(two, n_head + (i - n_flag) * 9, 9);
            if(j == 0 && m_head != 0)
                alpha = segtoint(one, 0, m_head);
            else
                alpha = segtoint(one, m_head + (j - m_flag) * 9, 9);

            product = alpha * bravo;
            if(product == 0)
                memset(temp, 0, 18);
            else
            {
                for(int k = 17; k > -1; k--)
                {
                    temp[k] = product % 10;
                    product /= 10;
                }
            }
            // add temp to answer from index backwards;
            index = 17;
            exit = false;
            while(!exit)
            {
                if(index < 0)
                    sum = answer[shift] + carry;
                else
                    sum = answer[shift] + temp[index] + carry;
                carry = sum / 10;
                answer[shift] = sum % 10;
                index--;
                shift--;
                if(carry == 0 && index < 0)
                    exit = true;
            }
        }
    }
    answer[m + n] = one[m] == two[n]? '+':'-';

    return answer;
}

По моему int main() ставлю

char* omega = multichar(delta, echo);
delete[] omega;
return 0;

Но это приводит к BLOCK IS VALID ошибке ... Почему я не могу удалить указатель?

Ответы [ 2 ]

2 голосов
/ 05 ноября 2011

По крайней мере, существует повреждение кучи, вызванное тем, что shift никогда не инициализируется. Ваш код записывает в answer[shift], и именно здесь происходит повреждение кучи.

Я ожидаю, что ваш компилятор будет предупреждать об этом. Я не тщательно проверил код и не удивлюсь, если появятся еще ошибки.


Обновление: Ответ выше был написан так, чтобы соответствовать исходному вопросу, который действительно не инициализировал shift. Обновленный код показывает, как shift инициализируется, но все еще пропускает важные части кода. Неважно, мой вывод тот же. Вы будете иметь повреждение кучи где-то из-за того, что shift выходит за пределы в какой-то момент в вашем цикле, который пишет в answer. Просто добавьте некоторые диагностические данные или используйте отладчик для проверки shift, и я уверен, что проблема станет ясной.

1 голос
/ 05 ноября 2011

Ваш расчет размера выключен. Например, для char_size(one) == 1 и char_size(one) == 1 вы получаете m = n = 0 и m_seg = n_seg = 1. Затем в первой итерации циклов у вас есть i = 0 и j = 0 и из этого:

shift = 0 + 0 - (1 + 1 - 0 - 0) * 9 + 17;

То есть shift = -1. Позже в этом цикле вы пишете в answer[shift], что выходит за пределы массива.

...