2016-12-16 16 views
1

입력에서 배열에 문자열을 저장하는 데 문제가 있습니다. 나는 EOF로 끝나는 입력에서 그것을 저장하고 길이가 임의의 문자열을 저장할 수 있습니다. 여기 내 코드는 다음과 같습니다 :알 수없는 길이의 문자열을 입력에서 알 수없는 양의 배열로 저장하는 방법은 무엇입니까?

char **list = (char**)malloc(sizeof(char*)); 
char c = getchar(); 
int i, j, count = 0; 
int size = 0; 
char * string = NULL 
while (c != EOF) 
{ 
    size = 0; 
    while (c != EOF && c != '\n') 
    { 
     string = (char*)realloc(string,size+1); //line 210 
     string[size] = c; 
     size++; 
     c = getchar(); 
    } 
    list = (char**)realloc(list, (count+1)*sizeof(char*)); 
    list[count] = string; 
    ++count; 
    string = NULL; 
    c = getchar(); 
} 
for (j = 0; j < count; ++j) //trying to print out all the strings 
{ 
    printf("%s\n", list[j]); //line 237 
} 
free(string); 
free(list); 
return (EXIT_SUCCESS); 

나는 모든 테스트가 성공했는지 여부도 테스트해야한다는 것을 알고 있지만, 지금은 내 문제가 아닙니다. -pedantic -Wall의 gcc로 컴파일 할 때 프로그램이 제대로 작동하지만, Valgrind의 다음과 같은 오류를 제공합니다 : 프로그램의 마지막에 string을 보내고

==2601== Memcheck, a memory error detector 
==2601== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==2601== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info 
==2601== Command: ./a.out -g 
==2601== 
asd 
dsa 
==2601== Invalid read of size 1 
==2601== at 0x4C30F74: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==2601== by 0x4EA95DB: puts (ioputs.c:35) 
==2601== by 0x4008E8: main (testing.c:237) 
==2601== Address 0x52035c3 is 0 bytes after a block of size 3 alloc'd 
==2601== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==2601== by 0x40080D: main (testing.c:210) 
==2601== 
asd 
dsa 
==2601== 
==2601== HEAP SUMMARY: 
==2601==  in use at exit: 12 bytes in 4 blocks 
==2601== total heap usage: 14 allocs, 10 frees, 2,101 bytes allocated 
==2601== 
==2601== LEAK SUMMARY: 
==2601== definitely lost: 12 bytes in 4 blocks 
==2601== indirectly lost: 0 bytes in 0 blocks 
==2601==  possibly lost: 0 bytes in 0 blocks 
==2601== still reachable: 0 bytes in 0 blocks 
==2601==   suppressed: 0 bytes in 0 blocks 
==2601== Rerun with --leak-check=full to see details of leaked memory 
==2601== 
==2601== For counts of detected and suppressed errors, rerun with: -v 
==2601== ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 0 from 0) 
+1

또한'realloc'에'string'을 전달하기 전에'string * NULL;을 설정합니다. 따라서 이전 할당 및 모든 내용을 버립니다 (단 1 바이트였던 경우에도 마찬가지입니다). –

+0

''pocet '이란 무엇입니까? – jxh

+0

'list [count] = string;'충분하다'list [count] = malloc();'에 할당 된 메모리를 덮어 쓴다. – jxh

답변

1

대신 free을, 당신은 각각에 할당 된 메모리를 해제 할 필요가 읽고 문자열 :

string = realloc(string,size+2); 

당신은 다음과 같습니다

for (j = 0; j < count; j++)  
     free(list[j]); 
free(list); 

"Invalid read of size 1" 오류를 해결하려면, 당신은 변경해야 string의 색인으로 size을 사용하므로 할당에 '\ 0'을위한 공간을 추가하기 전에이 값을 증가시켜야합니다. 변수 이름이 좋을수록이 문제를 피할 수있었습니다. sizeindex으로 변경하십시오. 당신이 c을 필요도

참고는 EOF 문자를 저장하기 위해에 int 수 있으므로 변경 : 또한

int c = getchar(); 

,이 코드는 NUL로 문자열을 종료 실패합니다.

... 
string[size] = '\0'; // NUL terminate string 

list = realloc(list, (count+1)*sizeof(*list)); 
... 

이 프로그램의 시작 부분에 list 초기화, 아직 공간을 할당 할 필요가 없습니다, 당신은 너무, 어쨌든 보내고 최대 realloc 종료 :

char **list = NULL; 
당신은 추가해야합니다

그리고 malloc()realloc() 호출에서 캐스트를 제거했음을 유의하십시오. 이것들은 C 언어에서는 필요 없으며 대부분 코드를 복잡하게 만듭니다. 마찬가지로 여기에 sizeof(char*)을 사용하는 대신 sizeof(*list)을 사용했습니다. 오류가 발생하기 쉽고 훨씬 명확합니다.

+0

고마워, '자유로운'문제는 해결되었지만, '잘못된 읽기'문제는 계속됩니다. – shiftingsand

+0

@ shiftingsand-- 코드에서 다른 문제와 실수에 대해 더 많은 의견을 추가했습니다. –