flatronka
flatronka

Reputation: 1081

C strange array allocation behavior

I use xcode with c and I have a strange problem with the following code.

When the algorithm reaches the y[k] = 0.0 row in my conv function then the x array filled by 0-s, I must understand why, I already correct this error in my own way. The problem is not appear when I comment the second row and uncomment the third row in main function(see below). I know that I reallocate the array in generateSquareSignal, but this is not a reason for this bug I think.

 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]);
    }
 }
}

Upvotes: 0

Views: 135

Answers (3)

Mike
Mike

Reputation: 49403

There's a number of issues here... but most of them are style. The real problem is just the fact that you have a memory leak and that's causing your problem. If you're going to make a function that allocates memory, let it allocate the memory:

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

Changeing these two lines of code like this:

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

Will eliminate that memory leak, and will allow your code to be properly sized as you wish (an array big enough for 1000 doubles)


Just for fun, here's a few of the other points I'm thinking of:

  1. why do you need room for 1000 doubles when you're only storing 200 in there?
  2. length appears to be a constant, you can make it a global #define and then you don't have to worry about passing it around
  3. If you are going to pass length, you don't need to pass it twice to conv() because it's the same for input arrays
  4. You can eliminate your need to set y in the conv() loop by just memseting the first 200 spots to 0.0

Upvotes: 1

Bart van Ingen Schenau
Bart van Ingen Schenau

Reputation: 15768

Your problem is in this part of your code (with added line numbers)

 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 );

In line 2, you allocate memory to hold 1000 doubles.

In line 4, you overwrite the only reference you had to that memory with a reference to a buffer that holds 100 doubles. This creates a memory leak of the memory allocated in line 2.

In line 14, you tell the conv function that the variable output (which becomes y inside conv) can store 200 doubles (and conv implicitly presumes it can store at least that amount of data in there). This is not true as it actually refers to a block of 100 doubles. The result is that conv writes outside of the bounds of the buffer referred to by output and y, which causes undefined behaviour. In your case, the undefined behaviour happens to be that the spill-over ends up in the memory block that was allocated next, which is the one referred to by input1 and x.

In the end, the root-cause for the bug is indeed the new allocation made in generateSquareSignal that overwrites the previous allocation for output.

Upvotes: 3

hyde
hyde

Reputation: 62797

You set output to point to malloced array with size of length. Then you use it beyond that. Result is pretty random... The malloc for 10*length does nothing (except leak memory) because you overwrite it's return value on the next line with return value of generateSquareSignal...

Upvotes: 3

Related Questions