2010-07-26 4 views
1

this topic에서 영감을 얻어 필자는 정확히 수행하는 간단한 프로그램을 작성하기로 결정했습니다.
로직이 복잡하지 않고 시간의 75 %를 작동하는 프로그램이 있습니다. 요청 된 숫자의 수는 #define BUFSIZE x으로 정의됩니다. 여기서 x은 임의의 int 일 수 있습니다.
((BUFSIZE+1) % sizeof(int)) == 0 일 때 문제가 발생합니다.프로그램의 오작동 시간의 25 %

예를 들어, BUFSIZE=10 인 경우 BUFSIZE=11이 이상한 동작을하면 프로그램이 올바르게 작동합니다.

#include <stdio.h> 
#include <stdlib.h> 
#define BUFSIZE 7 

int max(int *buf); 

int main() 
{ 
    int bufsize = BUFSIZE, *buf = malloc(sizeof(int[bufsize])); 

    // read values 
    int *ptr = buf; 
    while(--bufsize + 1) 
    { 
     printf("Input %d: ", BUFSIZE - bufsize); 
     scanf("%d", ptr); 
     ++ptr; 
    } 

    // reset pointer and determine max 
    ptr = buf; 
    printf("\nMax: %d\n", max(ptr)); 
    // cleanup 
    free(buf); 
    ptr = NULL; 
    buf = NULL; 

    exit(EXIT_SUCCESS); 
} 

int max(int *buf) 
{ 
    int max = 0; 
    while(*buf) 
    { 
     printf("%d\n", *buf); 
     if(*buf > max) max = *buf; 
     ++buf; 
    } 
    return max; 
} 

AND (올바른) BUFSIZE = 2 BUFSIZE = 3 (잘못된) 일부 샘플 출력 : 여기

는 소스 코드이다.

suze:/home/born05/htdocs/experiments/c# gcc input.c && ./a.out 
Input 1: 12 
Input 2: 23 
12 
23 

Max: 23 

suze:/home/born05/htdocs/experiments/c# gcc input.c && ./a.out 
Input 1: 12 
Input 2: 23 
Input 3: 34 
12 
23 
34 
135153 

Max: 135153 

매우 논리적 인 느낌이 들지만,이 비웃음의 정확한 원인에 대해 내 손가락을 댈 수 없습니다. 누군가 나에게 (아마도 명백한) 결함을 지적 할 수 있습니까?

+0

를 어? 당신은'buf [3]'와'buf [4]'에서 각각 센티넬 값을 사용하고 있지만, 크기는 각각 2와 3입니다. – falstro

답변

5

이것은 실제적으로 이것은 BUFSIZE의 모든 값에 대해 작동하는 순수한 행운입니다. (실제로, 나를 위해, 그것은 BUFSIZE=2에 부서진다). 이유는 다음과 같습니다.

while(*buf) 

버퍼의 끝을 확인하는 적절한 방법이 아닙니다. 이것은 buf이 가리키는 주소에 값을로드하고 내용이 0인지 확인합니다. 버퍼의 끝 부분에 명시 적으로 0을 넣지는 않았으므로 항상 true가 될 수는 없으며 루프는 잠재적으로 영원히 계속 실행되어 buf 배열의 끝까지 지나가고 정의되지 않은 동작을 호출합니다.

당신이 중 하나는 buf 배열의 마지막에 추가 요소를 할당하고 0으로 설정 (그러나 사용자가 입력으로 0를 입력하면 다음 프로그램이 잘 작동하지 않습니다), 또는 명시 적으로 buf의 크기를 통과해야 max 함수에 추가하고 루핑을 중단해야하는 시점을 결정하는 데 사용하십시오.

+0

그래서 배열을 반복하는 방법이 올바르지 않습니다. 이것을하기위한 적절한 방법은 무엇입니까? 'max()'에 길이를 전달할 필요가 있을까요? –

+0

예, 편집했습니다. 가장 좋은 방법은 buf 길이를 max로 전달한 다음 for (int i = 0; i

+0

좋아,'max()'의 프로토 타입을 바 꾸었습니다. 이제 매력처럼 작동합니다. 이런 종류의 것들에 대한 설명에 익숙해지는 것은 어렵습니다 (PHP 세계에서 올 때). –

2

int bufsize = BUFSIZE, *buf = malloc(sizeof(int[bufsize])); 

대신 당신이 BUFSIZE 정수와 하나 개의 여분의 정수를 포함하는 메모리를 필요로 하나 개의 정수 (sizeof(int[bufsize])sizeof(int*)로 평가)에 대한 메모리를 할당

현재 코드에서
int bufsize = BUFSIZE, *buf = malloc(sizeof(int[BUFSIZE + 1])); 
buf[BUFSIZE] = 0; 

해야한다 나중에 null.

현재 코드에는 합법적으로 할당되지 않은 메모리를 사용하는 소위 정의되지 않은 동작이 있습니다. 귀하의 경우 때때로 때로는 작동하지 않습니다. 적어도 지금은 원자력 발전소를 통제해야 할 때가 아닙니다.

1

buf가 null로 끝나는 문자열 배열 인 것으로 간주합니다. 일 수 있습니다. 데이터 값이 절대 0이 아니며 실제로 0을 넣는 경우 (프로그램에서 수행하지 않는 경우) 수행하십시오.

오히려 이런 일에 최대() 함수를 변경 (조정 프로토 타입 따라 위치를 호출) 시도 :

int max(int *buf, int count) 
{ 
    int max = 0; 

    // Check inputs 
    if (buf == NULL || count <= 0) 
    { 
     printf("max(): bad parameter(s)\n"); 
     return 0; 
    } 

    while(count--) 
    { 
     printf("%d\n", *buf); 
     if(*buf > max) max = *buf; 
     ++buf; 
    } 
    return max; 
} 
+0

감사합니다. 필자의 시스템에서 입력을 확인해야합니다. –