2012-11-30 3 views
0

xcode를 C와 함께 사용하고 다음 코드에 이상한 문제가 있습니다.이상한 배열 할당 동작

알고리즘이 conv 함수에서 y [k] = 0.0 행에 도달하면 x 배열이 0으로 채워질 때, 나는 왜 내 자신의 방식으로이 오류를 이미 수정했는지 이해해야합니다. 두 번째 행에 주석을 달고 main 함수의 세 번째 행의 주석 처리를 제거하면 문제가 나타나지 않습니다 (아래 참조). 나는 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

에 처음으로 200 점을 memseting하여 conv() 루프 y을 설정하는 당신의 필요를 제거 할 수 있습니다 : http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc –

답변

3

이 부분에 문제가 있습니다. 2 호선에서

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

(추가 회선 번호) 코드, 당신은 1000 루타를 개최 메모리를 할당합니다.

라인 4에서는 100 개의 double을 저장하는 버퍼에 대한 참조로 해당 메모리에 대한 참조 만 덮어 씁니다. 이것은 2

라인 (14)에서 암시 그것이에 저장할 수 추정 (conv 내부 y된다) 가변 output 200 복식 (및 conv를 저장할 수있는 conv 함수 말해 줄에 할당 된 메모리의 메모리 누수를 작성 거기에 최소한의 양의 데이터). 이것은 사실 100 배가되는 블록을 가리키는 것이기 때문에 사실이 아닙니다. 결과적으로 conv은 정의되지 않은 동작을 일으키는 outputy에 의해 참조되는 버퍼 경계 외부에서 씁니다. 경우에 정의되지 않은 동작은 다음에 할당 된 메모리 블록에서 스필 오버가 끝나는 것입니다.이 메모리 블록은 input1x에 의해 참조되는 것입니다.

결국 버그의 근본 원인은 실제로 output의 이전 할당을 덮어 쓰는 generateSquareSignal의 새로운 할당입니다.

3

출력을 크기가 malloced 인 배열을 가리 키도록 설정합니다. 그런 다음 그것을 넘어서 사용하십시오. 결과는 꽤 무작위입니다. 10 * 길이에 대한 malloc은 반환 값이 generateSquareSignal 인 결과 값을 겹쳐 쓰므로 아무 것도하지 않습니다 (누설 메모리 제외).

+0

이 malloc으로 메모리 누수가 발생한다는 것을 알고 있지만 다른 함수에서 0으로 채워진 배열을 얻는 이유는 무엇입니까? 귀하의 대답을 주셔서 감사합니다 – flatronka

+0

가능한 경우 generateSquare 신호에서 프로그램이 반환 할 때 신호 변수를 무료로? – flatronka

+0

또 다른 대답은이 특정 코드에서 어떤 일이 일어 났는지에 대해 더 많이 알려주지 만 중요한 점은 버퍼 오버런 (버퍼 오버런이 발생하면 메모리에 쓰기, , 결과는 "무작위", 정의되지 않은 것입니다. * 운이 좋다면 빠른 충돌 일 수 있습니다. – hyde

1

여기에는 여러 가지 문제가 있지만 그 중 대부분은 스타일입니다. 진짜 문제는 당신이 메모리 누출을 가지고 있고 그게 당신 문제를 일으키는 것입니다. 같은 코드의 두 라인 Changeing

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

: 메모리를 할당하는 함수를 만들려고하는 경우는 메모리를 할당 할 수

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

가 메모리 누수를 제거하는 것, 그리고 것이다 당신이


그냥 재미가, 여기에 내가 생각하고 다른 지점의 약간의 (1000 두 배만큼 큰 배열) 원하는대로 코드에 적당한 크기로 할 수 있도록 :

  1. 왜 거기에 200 개를 저장할 때 1000 두 배의 공간이 필요합니까?
  2. length
  3. 가 일정하게 나타납니다, 당신은 그것을 글로벌 # 정의 할 수 있습니다 다음 당신은 당신이 길이를 통과하기 위하여려고하는 경우에 주위
  4. 그것을 통과에 대해 걱정할 필요가 없습니다, 당신은 그것을 통과 할 필요가 없습니다 이 input 배열
  5. 에 대해 동일한 때문에 두 번 conv()에 당신은 malloc``의 반환을 캐스팅하지 않습니다 0.0
+0

당신의 대답과 관찰에 감사드립니다, 나는 그 문제가 메모리 누수로부터 왔지만, 누수가 이런 종류의 에러를 일으키지 않을 수 있다는 것을 알고 있습니다. 메모리에 약간의 쓰레기가 남아 있습니다. – flatronka

+1

@flatronka - 당신 말이 맞아요. 누수가 원인은 아니지만, 제 수정 사항이'generateSquareSignal()'에서 할당되는 두 가지, 누수 및 크기가 변경되었음을 알 수 있습니다. '100 * sizeof (double)'이 나오기 전에,'conv()'함수는 최소한'sizeof (double)'가 될 것으로 기대하고 있었기 때문에 배열을 오버 플로우 시켰고 거기서 문제가 발생했습니다. – Mike