2012-09-14 2 views
2

동적 배열에 문제가 있으며 malloc입니다. 나는 C에 상당히 익숙하다. 그래서 어떤 신기한 실수라도 변명해라.동적 배열 malloc이 별도의 배열을 비 웁니다.

문제는 배열 (이 경우 input_string)을 만들고 func2에 전달하는 것입니다. 그런 다음 func2 테스트에서 input_string의 첫 번째 요소를 출력합니다.

malloc 전에 첫 번째 인쇄물에서 예상대로 작동하지만 malloc 이후에는 아무 것도 인쇄되지 않습니다. 이것은 사이에 이상한 내게 보인다 printf 진술에 나는 input_string에 아무 것도하지 않는다.

나는이 배열을 잘못 처리하고 있다고 가정하고 있지만 확실하지 않습니다. 여기

문제의 코드 조각입니다 :

... // includes not in snippet 

/* CONSTANTS */ 
#define LINE_LEN 80 

/* Function declarations */ 
char* func1(void); 
char* func2(int tl, char* input_string); 

int main(void) { 
    char* input_string; 
    int tab_length; 
    char* output_string; 

    input_string = func1(); 
    output_string = func2(tl, input_string); 

    return 0; 
} 

char* func1(void) { 
    char cur_char; 
    char* input_ptr; 
    char input_string[LINE_LEN]; 
    while ((cur_char = getchar()) != '\n' && chars_read < 80) { 
     // iterate and create the array here 
    } 
    input_ptr = &input_string[0]; /* set pointer to address of 0th index */ 
    return input_ptr; 
} 

char* func2(int tl, char* input_string) { 
    int n = 0, output_idx = 0; 
    char* output_ptr; 
    printf("\nBefore malloc: %c ", *(input_string)); 
    output_ptr = malloc(tab_length * chars_read+1); 
    if (output_ptr == NULL) { 
      printf("Failed to allocate memory for output_ptr.\nExiting"); 
      exit(1); 
    } 
    printf("\nAfter malloc: %c ", *(input_string)); 
    ... 
    return output_ptr; 
} 

P.s 업데이트 : 모든 선언되지 않은 변수는이 코드 조각의 외부에 선언되어있다. 모든 답변과 조언을

업데이트

감사합니다. 대단히 감사합니다.

+0

어떻게'input_string'을 초기화합니까? 그것을 위해 메모리를 할당합니까? "아무것도 인쇄하지 않는다"는 것은 무엇을 의미합니까? – JohnB

+0

경고와 함께 컴파일 했습니까? 나는. (gcc 사용) $ gcc -Wall -Wextra -pedantic -std = c89 ... – Morpfh

+0

다음과 같이 input_string을 인스턴스화합니다. char * input_ptr; char input_string [LINE_LEN]; 그런 다음 몇 가지 물건을 추가하고 input_ptr을 func()에 전달합니다. – calderonmluis

답변

2

func1 임시 문자열에 대한 포인터를 반환합니다. 당신은 그것을 할당하지 않았다. 이렇게하면 정의되지 않은 동작이 발생합니다.

대신이 작업을 수행해야합니다

char* func1(void) { 
    char cur_char; 
    char* input_ptr = (char*)malloc(LINE_LEN * sizeof(char)); 
    while ((cur_char = getchar()) != '\n' && chars_read < 80) { 
     // iterate and create the array here 
    } 
    return input_ptr; 
} 

흥미롭게도, 당신은 func2 내부 malloc을 사용했다.

작업이 끝나면 free으로 전화하여 메모리를 해제해야합니다.

int main(void) { 
    char* input_string; 
    int tab_length; 
    char* output_string; 

    input_string = func1(); 
    output_string = func2(tl, input_string); 

    free(input_string); 
    free(output_string);  

    return 0; 
} 
+0

완벽한, 고마워! – calderonmluis

2

한 주요 문제는 당신이 로컬 배열에 대한 포인터를 반환한다는 것입니다 : 당신은 로컬 배열 input_string (그것의 제로 번째 요소)를 가리 키도록 input_ptr을 설정 한

char* func1(void) 
{ 
    char cur_char; 
    char* input_ptr; 
    char input_string[LINE_LEN]; 
    while ((cur_char = getchar()) != '\n' && chars_read < 80) { 
     // iterate and create the array here 
    } 
    input_ptr = &input_string[0]; /* set pointer to address of 0th index */ 
    return input_ptr; 
} 

및 그 포인터를 반환하십시오. 함수가 반환되면 포인터가 유효하지 않습니다. 공간은 다른 용도로 재사용됩니다.

어쨌든 컴파일러 경고를받지 못하면 더 많은 경고를 설정하여 컴파일해야합니다. 경고를 무시할 수있는 이유를 알기까지는 경고를 무시해서는 안됩니다. 나는 항상 -Wall -Wextra을 사용하고, 항상 항상 -Wall을 사용합니다.


Morpfh로 포인트를 밖으로, GCC 포인터를 반환에 대해 경고하지 않습니다 (4.7.1 맥 OS X 10.7.4에서 테스트), 그래서 당신은 컴파일러의 도움없이 그 인식해야 할 것이다. (return input_string; 또는 return &input_string[0];으로 변경하면 컴파일러에서 유용한 경고를 표시합니다.)

또한 코드를 컴파일 가능한 단위로 변환하는 동안 나는 EOF를 처리하지 않고, getchar()의 결과를 char에 할당합니다. int (이 문제에 대한 다른 설명은 다른 많은 질문 중에서 'fgetc() checking EOF' 참조)을 반환하기 때문에 그렇게해서는 안됩니다. 또한 문자열이 null로 끝나는 지 확인해야합니다. 또한 상수를 반복하지 않아야하므로 조건에서 80을 사용하는 대신 LINE_LEN을 사용하십시오 (또는 더 좋게는 sizeof(input_string)-1). 그리고 당신은 off-by-one 버퍼 오버 플로우에주의해야합니다. 그래서, 당신의 func1() 내 컴파일 가능한 버전이었다가 로컬 포인터를 반환하기 때문에

#include <stdio.h> 
#include <stdlib.h> 
#define LINE_LEN 80 
extern char *func1(void); 
char *func1(void) 
{ 
    int cur_char; 
    char *input_ptr; 
    int chars_read = 0; 
    char input_string[LINE_LEN+1]; 

    while ((cur_char = getchar()) != EOF && cur_char != '\n' && chars_read < LINE_LEN) 
     input_string[chars_read++] = cur_char; 

    input_string[chars_read] = '\0'; 
    input_ptr = &input_string[0]; /* set pointer to address of 0th index */ 
    return input_ptr; 
} 

이 여전히 코드를 나뉩니다.

+0

팁을 주셔서 감사합니다. 앞으로 컴파일 할 때이 플래그들을 확실히 사용할 것입니다. – calderonmluis

+0

gcc를 사용하고 -Wall -Wextra -pedantic을 사용하여 컴파일해도 이에 대해 경고하지 않습니다. 그 이유는 그가 input_ptr을 반환하고 & input_string [0]을 반환하지 않기 때문입니다. - 조금 까다 롭습니다. – Morpfh