2012-11-30 80 views
0

我使用c代码与c和我有一个奇怪的问题,下面的代码。C奇怪的数组分配行为

当算法达到在y [K] = 0.0行中我CONV功能那么x阵列由0-S填充,我必须明白为什么,我已经在我自己的方式纠正这种错误。 当我评论第二行并取消注释主函数中的第三行时(见下文),则不会出现问题。我知道我重新分配了generateSquareSignal中的数组,但这不是我认为的这个错误的原因。

int length = 100; 
double *output = (double*) malloc(10 * length * sizeof(double)); 
//double *output; 
output = generateSquareSignal(length); 
double *input1 = (double*) malloc(length * sizeof(double)); 
double *input2 = (double*) malloc(length * sizeof(double)); 

for (int i = 0; i < length; i++) { 
     input2[i] = output[i]; 
     input1[i] = output[i]; 
       //printf("-%d=%lf\n",i ,input1[i]); 
} 

conv(input1, length, input2, length, output, 2 * length); 


double* generateSquareSignal(int length) { 

    printf("double* generateSquareSignal(int length)\n"); 

    double *signal = (double*) malloc(length * sizeof(double)); 

    int length_period = length/kPeriodSignal; 
    for(int i=0; i < length; i++) { 
    if (i % (length_period) < (length_period/2)) { 
     signal[i] = 1.0; 
    } else { 
     signal[i] = -1.0; 
    } 
    //printf("%d. - %lf\n", i, signal[i]); 
} 

return signal; 
} 



void conv(double *x, int N_signal, 
         double *h, int N_kernel, 
         double *y, int N_output) { 
int k; 
for(k = 0; k < N_signal + N_kernel; k++) { 
    y[k] = 0.0; 
} 

for (int i = 0; i < N_signal; i++) { 
    printf("%lf-%lf\n", x[i], y[i]); 
} 


for(int i = 0; i < N_signal; i++) { 
    for(int j = 0; j < N_kernel; j++) { 
     double xx = x[i]; 
     double hh = h[j]; 
     double yy = y[i + j]; 
     y[i + j] += x[i] * h[j]; 
     //printf("=%lf\n", y[i + j]); 
    } 
} 
} 
+0

不投malloc'的'返回设置yconv()循环: http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc –

回答

3

你的问题是在这部分你的问题代码(附加行号)

1 int length = 100; 
2 double *output = (double*) malloc(10 * length * sizeof(double)); 
3 //double *output; 
4 output = generateSquareSignal(length); 
/* ... snipped line 5 to 12 */ 
13 
14 conv(input1, length, input2, length, output, 2 * length); 

在第2行中,您分配内存以保存1000个双打。

在第4行,则覆盖你必须该存储器与到保持100个双打缓冲剂的参考唯一参考。这在线路分配的存储器的存储器泄漏2.

在第14行,你告诉conv函数,变量output(它成为y内部conv)可存储200个双打(和conv隐含假定它可以在存储那里的数据量最少)。这是不正确的,因为它实际上是指100块双打的块。结果是conv写在outputy所指的缓冲区的边界之外,这导致未定义的行为。 在你的情况下,不确定的行为恰好是外溢在未来被分配的内存块,这是input1x提到的一个结束。

最后,错误的根本原因实际上是generateSquareSignal中的新分配,它将覆盖先前的分配output

3

您将输出设置为指向长度为大小的malloced数组。然后你使用它。结果是非常随机的... 10 *长度的malloc什么也没有(除了泄漏内存),因为你覆盖它的下一行返回值generateSquareSignal的返回值...

+0

我知道我用这个malloc导致了内存泄漏,但是为什么我在另一个函数中得到一个由0填充的数组?感谢您的回答 – flatronka

+0

当程序从generateSquare信号返回时释放信号变量可能吗? – flatronka

+0

另一个答案告诉我们更多关于在这个特定代码中可能发生的事情,但重要的一点是,如果你有缓冲区溢出(意思是:在分配块结束后写入内存,在其外面,破坏其他任何可能存在的地方) ,结果是“随机的”,未定义的,如果你是幸运的,可能会快速崩溃。 – hyde

1

这里有很多问题......但大多数都是风格。真正的问题在于你有内存泄漏并导致你的问题。如果你要作出这样的分配内存的功能,让它分配内存:

double *output = (double*) malloc(10 * length * sizeof(double)); 
output = generateSquareSignal(length); 

量变到质变的这两行代码是这样的:

double *output; 
output = generateSquareSignal(10 * length); 

将消除内存泄漏,并会允许适当调整了您的代码,你想(数组足够大,1000个双打)


只是为了好玩,这里有几个我想另一点:

  1. 为什么你需要空间1000个双打,当你只在那里存储200?
  2. length似乎是一个常数,你可以把它在全球的#define,然后你不必担心周围传递
  3. 如果你要通过长度,你不需要将它传递两次conv(),因为它是同为input阵列
  4. 您可以消除您需要通过只是memseting第200个点至0.0
+0

感谢您的回答和观察,我知道问题来自内存泄漏,但怎么可能泄漏不会导致这种错误只是内存中的一些垃圾。 – flatronka

+1

@flatronka - 你是对的,泄漏不是原因,但你会注意到我的修复改变了两件事,泄漏和从'generateSquareSignal()'分配的大小。在它是'100 * sizeof(double)'之前,那么'conv()'函数期望它至少是'200 * sizeof(double)',所以你溢出了你的数组,并且导致了那里的问题。 – Mike