何时删除karatsuba算法中分配的内存?

时间:2015-07-06 11:26:45

标签: c++ algorithm memory-management dynamic-memory-allocation


这是我对karatsuba算法的实现, 它在删除部分被注释时运行良好但是当我将其插入代码时,它会导致错误的输出! (例如,对于测试n = 5,a = b = {1,2,3,4,5})

void conv(int a[], int b[], int c[], int n)
{
    if (n == 1)
    {
        c[0] = a[0]*b[0];
        return;
    }
    int *C0 = new int[n];
    int *C1 = new int[n];
    int *C2 = new int[n];
    conv(a, b, C0, n/2);
    conv(a + n/2, b + n/2, C1, n/2);
    for (int i = 0; i < n/2; i++) 
        a[i] += a[i + n/2], b[i] += b[i + n/2];
    conv(a, b, C2, n/2);
    for (int i = 0; i < n/2; i++)
        a[i] -= a[i + n/2], b[i] -= b[i + n/2];
    for (int i = 0; i < n; i++)
    {
        c[i] += C0[i];
        c[i + n] += C1[i];
        c[i + n/2] += C2[i] - C1[i] - C0[i];
    }
/*  delete[] C0;
    delete[] C1;
    delete[] C2;*/
}

删除有什么问题?我是否以错误的方式释放了分配的内存? 提前谢谢!

3 个答案:

答案 0 :(得分:0)

您可以将它们声明为向量,而不是将它们声明为指针,然后您不必担心删除。这里删除的问题在你的代码参数中,你实际上是将c作为指针发送,所以当你删除指针时,你仍然指向你删除的地址而不是值。

答案 1 :(得分:0)

在这个循环中:

for (int i = 0; i < n; i++) {
        c[i] += C0[i];
        c[i + n] += C1[i];
        c[i + n/2] += C2[i] - C1[i] - C0[i];
    }

您要添加从未初始化的c元素。 (据推测,你打算将它们初始化为0,不是吗?)

我不知道你正在使用什么平台,但是我们假设它是一个平台,当没有内存被释放时,新的内存分配恰好全部为零,但是一旦释放内存分配,可以接收释放的分配,它将具有随机值。在这种情况下,删除delete语句使得所有内存分配更有可能是新鲜的,而包含它们使得内存块很可能被回收。

无论如何,使用未初始化的值是未定义的行为。您应该明确地将新分配的C0C1C2向量设置为0。

答案 2 :(得分:0)

您可以定义IntArray类,并在堆栈上创建它,而不是直接分配内存。通过这种方式,定义的类管理分配的内存本身。 (当它超出范围时,它释放其成员int数组'data'。)

class IntArray{
public:
int* data;
int n;
IntArray(int n){
    this->n = n;
    data = new int[n];
    for(int i=0; i<n; i++){
        data[i] = 0;
    }
}
~IntArray(){
    if(data != NULL){
        delete[] data;
        data = NULL;
    }
}

};

void conv(int a[], int b[], IntArray &c, int n)
{
if (n == 1)
{
    c.data[0] = a[0]*b[0];
    return;
}
/*
int *C0 = new int[n];
int *C1 = new int[n];
int *C2 = new int[n];
*/
IntArray C0(n);
IntArray C1(n);
IntArray C2(n);

conv(a, b, C0, n/2);
conv(a + n/2, b + n/2, C1, n/2);
for (int i = 0; i < n/2; i++)
    a[i] += a[i + n/2], b[i] += b[i + n/2];
conv(a, b, C2, n/2);
for (int i = 0; i < n/2; i++)
    a[i] -= a[i + n/2], b[i] -= b[i + n/2];
for (int i = 0; i < n; i++)
{
    c.data[i] += C0.data[i];
    c.data[i + n] += C1.data[i];
    c.data[i + n/2] += C2.data[i] - C1.data[i] - C0.data[i];
}
}