2011-12-21 3 views
0

내 코드가 나에게 segfault의 오류를 제공합니다 : 이해가 안되는 디버거 sizeof(char) 항상 당신 돈 이며, 오류가 stored_에서realloc을하고 strcpy를

char *stored_ = NULL; 
char testMessage[15]; 

//strcpy(stored_, testMessage); 

for (int a = 0;a < 10; a++) 
{ 
    sprintf(testMessage,"Message::%i\n",a); 
    printf("string is:%s;length is %i\n",testMessage,strlen(testMessage)); 

    stored_ = (char*) realloc (stored_, sizeof(char) * (strlen(testMessage) * (a+1))); 

    strcpy(&stored_[a], testMessage); 
} 

for (int b = 0;b < 10; b++) 
{ 
    printf("inside:|%s|\n",stored_[b]); 
} 
+0

segfault는 어떤 라인에서 발생합니까? –

+0

끝에서 널 종료 문자 ('\ 0')를위한 추가 공간을 추가해야합니다. –

답변

5

주먹을 값을 인쇄에서 온다 말한다 그것으로 번식 할 필요가 없습니다. 즉

malloc (strlen (string) + 1); 

, 당신은 끝에 널 바이트 공간이 필요 : 당신은 문자열을위한 공간을 할당 할 때

둘째, 당신은 사용해야합니다.

세 번째로 문자 포인터와 문자 포인터 사이에 혼동스러워 보입니다. 포인터는입니다. stored_은 한 블록의 문자이며 stored_[1]stored_[0]을 1 바이트 밖에 초과하지 않으므로 문자열을 저장할 공간이 충분하지 않습니다.

stored_[n], n=: 0 1 2 3 
       +---+---+---+---+ 
       | | | | |... 
       +---+---+---+---+ 
       each of these cells is a single byte. 

당신은 (스파 스 인덱스를 사용하여) 각 요소에 대해 충분한 공간을 남겨두고 자 자신의 단일 블록을 관리하기 위해, 또는 인덱스 0, 1, 2 등으로 문자 포인터의 블록을해야 하나 on하지만 문자열 할당을 별도로 관리해야합니다.

다음 코드는이 후자의 일을 수행하는 방법을 보여줍니다 : 그것의 고기, 문자 포인터는 C 문자열을 형성 문자의 실제 배열에서 별도의의 배열의 할당입니다

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

int main (void) { 
    // An array of char pointers (C strings). 

    char **stored_ = NULL; 
    char testMessage[15]; 
    int i; 

    // Populate them. 

    for (i = 0; i < 10; i++) { 
     sprintf (testMessage,"Message::%i",i); 
     printf ("string is:%s;length is %i\n",testMessage,strlen(testMessage)); 

     // Reallocate array of char *, allocate room for string, then store it. 

     stored_ = realloc (stored_,sizeof (char*) * (i + 1)); 
     stored_[i] = malloc (strlen (testMessage) + 1); 
     strcpy (stored_[i], testMessage); 
    } 

합니다.

다음 코드는 아래 코드를 인쇄하여 정리합니다.

// Print them. 

    for (i = 0; i < 10; i++) { 
     printf("inside:|%s|\n",stored_[i]); 
    } 

    // Free all memory and return. 

    for (i = 0; i < 10; i++) { 
     free (stored_[i]); 
    } 
    free (stored_); 

    return 0; 
} 

출력의 존재가 예상대로 :

이 방법
string is:Message::0;length is 10 
string is:Message::1;length is 10 
string is:Message::2;length is 10 
string is:Message::3;length is 10 
string is:Message::4;length is 10 
string is:Message::5;length is 10 
string is:Message::6;length is 10 
string is:Message::7;length is 10 
string is:Message::8;length is 10 
string is:Message::9;length is 10 
inside:|Message::0| 
inside:|Message::1| 
inside:|Message::2| 
inside:|Message::3| 
inside:|Message::4| 
inside:|Message::5| 
inside:|Message::6| 
inside:|Message::7| 
inside:|Message::8| 
inside:|Message::9| 

은, 각각의 셀은 문자의 배열에 대한 포인터이며, 별도로합니다 (C 문자열을 보유 함)이 할당 :

stored_[n], n=: 0 1 2 3 
       +---+---+---+---+ 
       | | | | |... 
       +---+---+---+---+ 
        | | | |  +----------------------+ 
        | | | +---> | character array here | 
        | | |   +----------------------+ 
        | | |   +----------------------+ 
        | | +-------> | character array here | 
        | |    +----------------------+ 
        | |    +----------------------+ 
        | +-----------> | character array here | 
        |     +----------------------+ 
        |     +----------------------+ 
        +---------------> | character array here | 
            +----------------------+ 
+0

네 번째로 % d가 아니고 % i입니다. –

+0

실제로'd'와'i'도 C99에서 똑같이 유효합니다. – paxdiablo

0

stored_의 문자열 길이를 올바르게 계산하지 않은 것처럼 보입니다.

testMessage부터 &stored_[loopindex]까지 지정하는 모든 루프. 이것이 의도 된 동작인지 확실하지 않지만, 여러분이하는 일이므로 10 번째 반복에서 문자열 "MMMMMMMMMessage::9\n"을 줄 것으로 기대됩니다.

어쨌든, testMessage는 같은 수의 문자는 항상, 그래서 stored_에 필요한 저장 공간은 다음과 같이 계산 될 수있다 :

strlen(testMessage) // length of str to place at &stored_[a] 
+ a     // the loop index, where you're inserting testMessage 
+ 1     // important! extra char to hold the null terminator 

이제까지 일을 잊지 마세요, C의 모든 문자열 공간이 있어야합니다 null terminator의 경우