为什么我不能释放动态内存?

时间:2011-11-05 17:51:13

标签: c++ arrays pointers dynamic destructor

修改

找到答案。这是位于

的逻辑错误
if(carry == 0 && index < 0)
    exit = true;

由于每个段以18位数字开头(因此{while}循环之前的index = 17;),当shift的值小于该值时,代码将继续写入answer[0]以外的值。我通过添加一个附加条件来解决退出标志。

很抱歉这个混乱。

原始问题

这是我写的一个函数,它以char数组的格式乘以两个整数,每个单元格代表一个十进制数字(例如,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 个答案:

答案 0 :(得分:2)

至少,由shift从未初始化的事实导致堆损坏。您的代码写入answer[shift],这将是堆损坏发生的地方。

我希望你的编译器会对此发出警告。我没有仔细检查代码,如果有更多错误也不会感到惊讶。


更新:上面的答案是为了解决确实没有初始化shift的原始问题。更新后的代码显示了shift的初始化方式,但仍然省略了代码的重要部分。无论如何,我的结论是一样的。由于shift在循环中的某个点写入answer,因此会在某处出现堆损坏。只需添加一些诊断输出或使用调试器来检查shift,我确信问题将变得清晰。

答案 1 :(得分:1)

您的尺寸计算已关闭。例如,对于char_size(one) == 1char_size(one) == 1,您可以获得m = n = 0m_seg = n_seg = 1。然后在循环的第一次迭代中,您有i = 0j = 0,并从中获取:

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

那是shift = -1。稍后在该循环中,您将写入answer[shift],这将超出数组的范围。