0

我将 xcode 与 c 一起使用,但下面的代码有一个奇怪的问题。

当算法到达我的 conv 函数中的 y[k] = 0.0 行时,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]);
    }
 }
}
4

3 回答 3

3

您将输出设置为指向长度大小的分配数组。然后你会使用它。结果非常随机... 10*length 的 malloc 什么都不做(泄漏内存除外),因为您在下一行用 generateSquareSignal 的返回值覆盖了它的返回值...

于 2012-11-30T17:46:36.933 回答
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(变为yinside conv)可以存储 200 个双精度数(并conv隐含地假定它可以在其中存储至少该数量的数据)。这不是真的,因为它实际上是指一个 100 个双打块。结果是conv写入超出了outputand引用的缓冲区的范围y,这会导致未定义的行为。在您的情况下,未定义的行为恰好是溢出最终出现在下一个分配的内存块中,这是由input1and引用的内存块x

最后,该错误的根本原因确实是新的分配generateSquareSignal覆盖了之前的分配output

于 2012-11-30T18:13:53.047 回答
1

这里有很多问题......但其中大部分是风格。真正的问题只是你有内存泄漏,这就是你的问题。如果你要创建一个分配内存的函数,让它分配内存:

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

像这样更改这两行代码:

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

将消除内存泄漏,并允许您的代码根据需要调整大小(一个足够大的数组,可容纳 1000 个双精度数)


只是为了好玩,以下是我正在考虑的其他几点:

  1. 当你只在里面存放 200 个时,为什么你需要 1000 个双打的空间?
  2. length似乎是一个常数,您可以将其设为全局#define,然后您不必担心传递它
  3. 如果要传递长度,则不需要将其传递两次,conv()因为input数组相同
  4. 您只需将前 200 个点设置yconv()0.0
于 2012-11-30T18:42:48.063 回答