如何从输入中存储未知数量的未知长度字符串数组?
How to store an array of an unknown amount of strings of unknown length from input?
我无法将输入的字符串存储到数组中。我想从以 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);
我知道我还应该测试所有分配是否成功,但这不是我现在的问题。该程序在使用 gcc -Wall -pedantic 编译时工作正常,但 valgrind 给出以下错误:
==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)
您需要释放为您读取的每个字符串分配的内存,而不是在程序末尾 free
ing string
:
for (j = 0; j < count; j++)
free(list[j]);
free(list);
要修复 "Invalid read of size 1"
错误,您需要更改:
string = realloc(string,size+2);
您正在使用 size
作为 string
的索引,因此您需要在为分配中的“\0”添加 space 之前增加此值。更好的变量名将有助于避免这个问题。考虑将 size
更改为 index
.
另请注意,您需要 c
成为 int
才能存储 EOF
字符,因此请更改:
int c = getchar();
此外,此代码无法以 NUL
终止字符串。您需要添加:
...
string[size] = '[=13=]'; // NUL terminate string
list = realloc(list, (count+1)*sizeof(*list));
...
当你在程序开头初始化 list
时,还没有必要分配 space,你只是最终 realloc
ing 它,所以:
char **list = NULL;
请注意,我从对 malloc()
和 realloc()
的调用中删除了强制转换。这些在 C 中不需要,并且主要用于使代码混乱。同样,这里我没有使用sizeof(char*)
,而是使用了sizeof(*list)
,这样更不容易出错,也更加清晰。
我无法将输入的字符串存储到数组中。我想从以 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);
我知道我还应该测试所有分配是否成功,但这不是我现在的问题。该程序在使用 gcc -Wall -pedantic 编译时工作正常,但 valgrind 给出以下错误:
==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)
您需要释放为您读取的每个字符串分配的内存,而不是在程序末尾 free
ing string
:
for (j = 0; j < count; j++)
free(list[j]);
free(list);
要修复 "Invalid read of size 1"
错误,您需要更改:
string = realloc(string,size+2);
您正在使用 size
作为 string
的索引,因此您需要在为分配中的“\0”添加 space 之前增加此值。更好的变量名将有助于避免这个问题。考虑将 size
更改为 index
.
另请注意,您需要 c
成为 int
才能存储 EOF
字符,因此请更改:
int c = getchar();
此外,此代码无法以 NUL
终止字符串。您需要添加:
...
string[size] = '[=13=]'; // NUL terminate string
list = realloc(list, (count+1)*sizeof(*list));
...
当你在程序开头初始化 list
时,还没有必要分配 space,你只是最终 realloc
ing 它,所以:
char **list = NULL;
请注意,我从对 malloc()
和 realloc()
的调用中删除了强制转换。这些在 C 中不需要,并且主要用于使代码混乱。同样,这里我没有使用sizeof(char*)
,而是使用了sizeof(*list)
,这样更不容易出错,也更加清晰。