2012-04-06 2 views
-4

다음은 사용자가 알 수없는 단어 수를 입력 할 때까지 'E'이 입력 될 때까지 프로그램이 중지하고 입력 한 단어를 모두 인쇄해야하는 코드입니다. 그러나이 프로그램을 실행하면 세그먼트 화 오류가 발생합니다. 내가 가져서는 안되는 기억을 접 했니?배열 단어를 인쇄 할 때 세그먼테이션 오류가 발생합니다.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define CAPACITY 10 
#define NUM_OF_WORDS 10 
int main(void) 
{ 
    int num_words = 10; 
    char *word= malloc(CAPACITY*sizeof(char)); 
    char **w=(char **) malloc(num_words*sizeof(char)); 
    int i; 
    for(i = 0 ; scanf("%s", word)==1; ++i) 
    { 
     if(*word == 'E') 
      break; 
     if(i == num_words-1) 
      w = (char **)realloc(w, (num_words *=2) * sizeof(char)); 
     w[i] =(char *) malloc(strlen(word)+1 * sizeof(char)); 
     strcpy(w[i], word); 
    } 
    int x = 0; 
    for(x = 0 ; x<num_words ; x++) 
     printf("%s", w[x]); 
    return 0; 
} 
+1

이 무엇 입력을 충돌하게, 어떤 줄에 : 나는 당신이 사용하는 더 나을 거라고 생각? –

+0

@ 존 틴크가 옳다. "세분화 오류가 발생했습니다."테스트 한 결과 알지 못해서별로 도움이되지 않습니까? 즉시 충돌합니까? 특정 입력 후? 디버거에서 실행 했습니까? – abelenky

+0

데이터를 입력하지 못하고 프로그램이 어떤 것을 출력하려고하면 i seg를 받았습니다. 'printf'' for for '루프에서 에러 –

답변

0

num_wordsw 어레이의 현재의 최대 크기를 가변 내 보유하지만 실제로 어레이의 단어의 수와 동일하지 않다.

w 배열을 통해 반복 할 때 너무 많은 항목을 반복합니다. w의 일부 요소에 유효한 문자열이 없습니다.이 문자열을 인쇄하려고하면 segfault가 발생합니다.

+0

그래, 그게 문제라고 생각해. 그래서 그것들을 인쇄하는 더 좋은 해결책이 있니? –

+0

@ twain249 - malloc 된 버퍼에 따라 segfault가 발생할 수도 있고 그렇지 않을 수도 있습니다. malloc은 메모리가 0이 될 것이라고 보장하지 않습니다. – shf301

+0

오, 바보 같은 날, 난 그냥 num_words 대신에 사용할 수 –

1

귀하의 초기 할당 코드 읽

char *word = malloc(CAPACITY*sizeof(char)); 
char **w = (char **) malloc(num_words*sizeof(char)); 

는이 두 메모리의 10 바이트를 할당합니다. 당신의 두 번째 읽어야합니다

char **w = (char **) malloc(num_words*sizeof(char *)); 

또는 :

char **w = malloc(num_words*sizeof(*w)); 

는이 두 (원래 코드로 여덟 배 많은 메모리가 될 수 있음) 10 포인터에 대한 충분한 메모리를 할당합니다. 두 번째는 틀림없이 더 나은 스타일입니다. 첫 번째는 의심 할 여지없이 고전적인 스타일입니다. C에서 malloc()에 대한 캐스트는 필요하지 않습니다. C++에서는 그렇습니다.

전체적으로 문제가되지 않을 수도 있습니다. 거의 확실하게 기여 요인입니다.

또한 메모리 할당을 확인하지 않습니다. 그것은 권하지 않습니다. 항상 확인해야합니다.


이 코드 :

if (i == num_words-1) 
    w = (char **)realloc(w, (num_words *=2) * sizeof(char)); 

는 두 개의 계정 (및 이전에 진단 된 문제의 반복)에 화재로 재생 : 인수 목록에서

  1. 할당입니다. .. 일반적으로 좋은 생각이 아니라고 생각합니다. 그 자리에 코드를 작성하지 않을 것이며 코드가 포함 된 리뷰를 요청받은 코드를 다시 보내 드리겠습니다. 기술적으로 잘못된 것은 아닙니다. 그것은 효과가있을 것이다. 그러나 그것은 유지 보수 프로그래머가 더 쉽게 삶을 사는 것은 아닙니다.

  2. w과 같은 포인터를 다시 할당하고 새 포인터를 동일한 포인터에 할당해서는 안됩니다. 메모리 할당에 실패하면 널 포인터가 반환되므로 이전 데이터에 대한 유일한 포인터가 손실되어 여전히 할당됩니다. 그것은 메모리 누수입니다. 또한 메모리 할당에 실패하면 할당 된 공간이 여전히 원래 크기이기 때문에 인수 목록에서 할당을 실행 취소해야합니다.

    if (i == num_words - 1) 
    { 
        size_t new_size = (num_words * 2); 
        char **new_data = realloc(w, new_size * sizeof(*new_data)); 
        if (new_data == 0) 
         ...handle error; w is still valid, and num_words is still correct too... 
        num_words = new_size; 
        w = new_data; 
    } 
    
관련 문제