[英]C - Array of Strings & Mysterious Valgrind Error
I'm trying to allocate a two-dimensional array of strings, where the last member is always a NULL pointer, ie an empty array consists of a single NULL pointer. 我正在尝试分配一个二维字符串数组,其中最后一个成员始终是NULL指针,即,一个空数组由一个NULL指针组成。 I keep getting Valgrind errors but I have no idea why. 我不断收到Valgrind错误,但我不知道为什么。
/*Initializes the string array to contain the initial
* NULL pointer, but nothing else.
* Returns: pointer to the array of strings that has one element
* (that contains NULL)
*/
char **init_array(void)
{
char **array = malloc(sizeof(char *));
array[0] = NULL;
return array;
}
/* Releases the memory used by the strings.
*/
void free_strings(char **array)
{
int i = 0;
while(array[i] != NULL){
free(array[i]);
i++;
}
//free(array[i]);
free(array);
}
/* Add <string> to the end of array <array>.
* Returns: pointer to the array after the string has been added.
*/
char **add_string(char **array, const char *string)
{
int i = 0;
while(array[i] != NULL){
i++;
}
array = realloc(array, (i+1) * sizeof(char *));
char *a = malloc(strlen(string)+1);
array[i] = malloc(strlen(string)+1);
strcpy(a, string);
strcpy(array[i], a);
free(a);
return array;
}
Here's the Valgrind error: 这是Valgrind错误:
==375== Invalid read of size 8 ==375== at 0x402FCE: add_string (strarray.c:40) ==375== by 0x401855: test_add_string (test_source.c:58) ==375== by 0x405F90: srunner_run_all (in /tmc/test/test) ==375== by 0x4028B2: tmc_run_tests (tmc-check.c:122) ==375== by 0x40256A: main (test_source.c:194) ==375== Address 0x518df08 is 0 bytes after a block of size 8 alloc'd ==375== at 0x4C245E2: realloc (vg_replace_malloc.c:525) ==375== by 0x402FF4: add_string (strarray.c:43) ==375== by 0x401855: test_add_string (test_source.c:58) ==375== by 0x405F90: srunner_run_all (in /tmc/test/test) ==375== by 0x4028B2: tmc_run_tests (tmc-check.c:122) ==375== by 0x40256A: main (test_source.c:194) ==375== ==375== Invalid read of size 8 ==375== at 0x4018F7: test_add_string (test_source.c:70) ==375== by 0x405F90: srunner_run_all (in /tmc/test/test) ==375== by 0x4028B2: tmc_run_tests (tmc-check.c:122) ==375== by 0x40256A: main (test_source.c:194) ==375== Address 0x518e308 == 375 ==大小为8的无效读取== 375 ==在0x402FCE:add_string(strarray.c:40)== 375 ==由0x401855:test_add_string(test_source.c:58)== 375 ==由0x405F90: srunner_run_all(在/ tmc / test / test中)== 375 ==通过0x4028B2:tmc_run_tests(tmc-check.c:122)== 375 ==通过0x40256A:main(test_source.c:194)== 375 ==地址0x518df08是大小为8的块之后的0字节== 375 ==在0x4C245E2:重新分配(vg_replace_malloc.c:525)== 375 ==通过0x402FF4:add_string(strarray.c:43)== 375 ==通过0x401855:test_add_string(test_source.c:58)== 375 ==通过0x405F90:srunner_run_all(在/ tmc / test / test中)== 375 ==通过0x4028B2:tmc_run_tests(tmc-check.c:122)== 375 == by 0x40256A:main(test_source.c:194)== 375 == == 375 ==大小为8的无效读取== 375 ==在0x4018F7:test_add_string(test_source.c:70)== 375 ==通过0x405F90:srunner_run_all(在/ tmc / test / test中)== 375 ==通过0x4028B2:tmc_run_tests(tmc-check.c:122)== 375 ==通过0x40256A:主(test_source.c:194)== 375 = =地址0x518e308 is 0 bytes after a block of size 40 alloc'd ==375== at 0x4C245E2: realloc (vg_replace_malloc.c:525) ==375== by 0x402FF4: add_string (strarray.c:43) ==375== by 0x401855: test_add_string (test_source.c:58) ==375== by 0x405F90: srunner_run_all (in /tmc/test/test) ==375== by 0x4028B2: tmc_run_tests (tmc-check.c:122) ==375== by 0x40256A: main (test_source.c:194) ==375== ==375== Invalid read of size 8 ==375== at 0x402F8D: free_strings (strarray.c:25) ==375== by 0x401AA6: test_add_string (test_source.c:91) ==375== by 0x405F90: srunner_run_all (in /tmc/test/test) ==375== by 0x4028B2: tmc_run_tests (tmc-check.c:122) ==375== by 0x40256A: main (test_source.c:194) ==375== Address 0x518e308 is 0 bytes after a block of size 40 alloc'd ==375== at 0x4C245E2: realloc (vg_replace_malloc.c:525) ==375== by 0x402FF4: add_string (strarray.c:43) ==375== by 0x401855: test_add_string (test_source.c:58) ==375== by 0x405F90: srunner_run_all (in /tmc/test/test) ==37 在大小为40的块之后的0字节== 375 ==在0x4C245E2:重新分配(vg_replace_malloc.c:525)== 375 ==通过0x402FF4:add_string(strarray.c:43)== 375 ==通过0x401855:test_add_string(test_source.c:58)== 375 ==通过0x405F90:srunner_run_all(在/ tmc / test / test中)== 375 ==通过0x4028B2:tmc_run_tests(tmc-check.c:122)== 375 = =通过0x40256A:主(test_source.c:194)== 375 == == 375 ==无效的8号读取== 375 ==在0x402F8D:free_strings(strarray.c:25)== 375 ==通过0x401AA6 :test_add_string(test_source.c:91)== 375 ==通过0x405F90:srunner_run_all(在/ tmc / test / test中)== 375 ==通过0x4028B2:tmc_run_tests(tmc-check.c:122)== 375 ==通过0x40256A:main(test_source.c:194)== 375 ==地址0x518e308是大小为40的块之后的0个字节alloc = d == 375 ==在0x4C245E2:重新分配(vg_replace_malloc.c:525)== 375 = =通过0x402FF4:add_string(strarray.c:43)== 375 ==通过0x401855:test_add_string(test_source.c:58)== 375 ==通过0x405F90:srunner_run_all(在/ tmc / test / test中)== 37 5== by 0x4028B2: tmc_run_tests (tmc-check.c:122) ==375== by 0x40256A: main (test_source.c:194) ==375== ==376== Invalid read of size 8 ==376== at 0x402FCE: add_string (strarray.c:40) ==376== by 0x401DCD: test_make_lower (test_source.c:111) ==376== by 0x405F90: srunner_run_all (in /tmc/test/test) ==376== by 0x4028B2: tmc_run_tests (tmc-check.c:122) ==376== by 0x40256A: main (test_source.c:194) ==376== Address 0x518e6d8 is 0 bytes after a block of size 8 alloc'd ==376== at 0x4C245E2: realloc (vg_replace_malloc.c:525) ==376== by 0x402FF4: add_string (strarray.c:43) ==376== by 0x401DCD: test_make_lower (test_source.c:111) ==376== by 0x405F90: srunner_run_all (in /tmc/test/test) ==376== by 0x4028B2: tmc_run_tests (tmc-check.c:122) ==376== by 0x40256A: main (test_source.c:194) ==376== ==376== Invalid read of size 8 ==376== at 0x402F8D: free_strings (strarray.c:25) ==376== by 0x401F5C: test_make_lower (test_source.c:130) ==376== by 0x405F90: s 5 ==通过0x4028B2:tmc_run_tests(tmc-check.c:122)== 375 ==通过0x40256A:main(test_source.c:194)== 375 == == 376 ==大小8的无效读取== 376 ==在0x402FCE:add_string(strarray.c:40)== 376 ==通过0x401DCD:test_make_lower(test_source.c:111)== 376 ==通过0x405F90:srunner_run_all(在/ tmc / test / test中)== 376 ==通过0x4028B2:tmc_run_tests(tmc-check.c:122)== 376 ==通过0x40256A:main(test_source.c:194)== 376 ==地址0x518e6d8是分配了大小为8的块后的0字节== 376 ==在0x4C245E2:重新分配(vg_replace_malloc.c:525)== 376 ==通过0x402FF4:add_string(strarray.c:43)== 376 ==通过0x401DCD:test_make_lower(test_source.c:111)== 376 ==通过0x405F90:srunner_run_all(在/ tmc / test / test中)== 376 ==通过0x4028B2:tmc_run_tests(tmc-check.c:122)== 376 ==通过0x40256A:main(test_source.c:194) == 376 == == 376 ==大小为8的无效读取== 376 ==在0x402F8D:free_strings(strarray.c:25)== 376 ==由0x401F5C:test_make_lower(test_source.c:130)== 376 ==通过0x405F90:s runner_run_all (in /tmc/test/test) ==376== by 0x4028B2: tmc_run_tests (tmc-check.c:122) ==376== by 0x40256A: main (test_source.c:194) ==376== Address 0x518e9d0 is 0 bytes after a block of size 32 alloc'd ==376== at 0x4C245E2: realloc (vg_replace_malloc.c:525) ==376== by 0x402FF4: add_string (strarray.c:43) ==376== by 0x401DCD: test_make_lower (test_source.c:111) ==376== by 0x405F90: srunner_run_all (in /tmc/test/test) ==376== by 0x4028B2: tmc_run_tests (tmc-check.c:122) ==376== by 0x40256A: main (test_source.c:194) ==376== ==377== Invalid read of size 8 ==377== at 0x402FCE: add_string (strarray.c:40) ==377== by 0x4022DB: test_sort_strings (test_source.c:155) ==377== by 0x405F90: srunner_run_all (in /tmc/test/test) ==377== by 0x4028B2: tmc_run_tests (tmc-check.c:122) ==377== by 0x40256A: main (test_source.c:194) ==377== Address 0x518f3e8 is 0 bytes after a block of size 8 alloc'd ==377== at 0x4C245E2: realloc (vg_replace_malloc.c:525) ==377== Runner_run_all(在/ tmc / test / test中)== 376 ==通过0x4028B2:tmc_run_tests(tmc-check.c:122)== 376 ==通过0x40256A:main(test_source.c:194)== 376 ==地址0x518e9d0是位于大小为32的块之后的0字节== 376 ==在0x4C245E2:重新分配(vg_replace_malloc.c:525)== 376 ==通过0x402FF4:add_string(strarray.c:43)== 376 ==通过0x401DCD:test_make_lower(test_source.c:111)== 376 ==通过0x405F90:srunner_run_all(在/ tmc / test / test中)== 376 ==通过0x4028B2:tmc_run_tests(tmc-check.c:122)== 376 == by 0x40256A:main(test_source.c:194)== 376 == == 377 ==大小为8的无效读取== 377 == at 0x402FCE:add_string(strarray.c:40)== 377 == by 0x4022DB:test_sort_strings(test_source.c:155)== 377 ==通过0x405F90:srunner_run_all(在/ tmc / test / test中)== 377 ==通过0x4028B2:tmc_run_tests(tmc-check.c:122)== 377 = = by 0x40256A:main(test_source.c:194)== 377 ==地址0x518f3e8是大小为8的块之后的0个字节alloc'd == 377 ==在0x4C245E2:realloc(vg_replace_malloc.c:525)== 377 == by 0x402FF4: add_string (strarray.c:43) ==377== by 0x4022DB: test_sort_strings (test_source.c:155) ==377== by 0x405F90: srunner_run_all (in /tmc/test/test) ==377== by 0x4028B2: tmc_run_tests (tmc-check.c:122) ==377== by 0x40256A: main (test_source.c:194) ==377== ==377== Invalid read of size 8 ==377== at 0x402F8D: free_strings (strarray.c:25) ==377== by 0x40246A: test_sort_strings (test_source.c:174) ==377== by 0x405F90: srunner_run_all (in /tmc/test/test) ==377== by 0x4028B2: tmc_run_tests (tmc-check.c:122) ==377== by 0x40256A: main (test_source.c:194) ==377== Address 0x518f6e0 is 0 bytes after a block of size 32 alloc'd ==377== at 0x4C245E2: realloc (vg_replace_malloc.c:525) ==377== by 0x402FF4: add_string (strarray.c:43) ==377== by 0x4022DB: test_sort_strings (test_source.c:155) ==377== by 0x405F90: srunner_run_all (in /tmc/test/test) ==377== by 0x4028B2: tmc_run_tests (tmc-check.c:122) ==377== by 0x40256A: main (test_source.c:194) = 通过0x402FF4:add_string(strarray.c:43)== 377 ==通过0x4022DB:test_sort_strings(test_source.c:155)== 377 ==通过0x405F90:srunner_run_all(在/ tmc / test / test中)== 377 ==通过0x4028B2:tmc_run_tests(tmc-check.c:122)== 377 ==通过0x40256A:main(test_source.c:194)== 377 == == 377 ==大小8的无效读取== 377 == 0x402F8D:free_strings(strarray.c:25)== 377 ==通过0x40246A:test_sort_strings(test_source.c:174)== 377 ==通过0x405F90:srunner_run_all(在/ tmc / test / test中)== 377 ==通过0x4028B2:tmc_run_tests(tmc-check.c:122)== 377 ==通过0x40256A:main(test_source.c:194)== 377 ==地址0x518f6e0是大小为32的块分配后的0字节== 377 ==在0x4C245E2:重新分配(vg_replace_malloc.c:525)== 377 ==通过0x402FF4:add_string(strarray.c:43)== 377 ==通过0x4022DB:test_sort_strings(test_source.c:155)== 377 ==通过0x405F90:srunner_run_all(在/ tmc / test / test中)== 377 ==通过0x4028B2:tmc_run_tests(tmc-check.c:122)== 377 ==通过0x40256A:主(test_source.c:194)= =377== = 377 ==
That's because you didn't add new NULL-terminator to the array add_string()
. 那是因为您没有向数组add_string()
添加新的NULL终止符。 So subsequent calls of add_array()
fail to find end of array without going out of bounds. 因此,随后对add_array()
调用无法找到数组的结尾而不会超出范围。
I think you need realloc with larger length: 我认为您需要重新分配更大的长度:
array = realloc(array, (i + 2) * sizeof(char *));
And then save NULL-terminator to array[i + 1]
: 然后将NULL终止符保存到array[i + 1]
:
array[i + 1] = NULL;
Why didn't you try using linked lists for that? 您为什么不尝试使用链接列表呢? I feel bad for realloc()
per each add_string()
我为每个add_string()
realloc()
感到add_string()
This function 该功能
char **add_string(char **array, const char *string)
{
int i = 0;
while(array[i] != NULL){
i++;
}
array = realloc(array, (i+1) * sizeof(char *));
char *a = malloc(strlen(string)+1);
array[i] = malloc(strlen(string)+1);
strcpy(a, string);
strcpy(array[i], a);
free(a);
return array;
}
is wrong. 是错的。 It does not add a new slot into the array and you do not set the last element to NULL. 它不会在阵列中添加新的插槽,并且您不会将最后一个元素设置为NULL。
The valid function can look like 有效功能可能看起来像
char **add_string( char **array, const char *string )
{
int i = 0;
while ( array[i++] != NULL );
array = realloc( array, ( i + 1 ) * sizeof( char * ) );
array[i] = NULL;
array[i-1] = malloc( strlen( string ) + 1 );
strcpy( array[i-1], string );
return array;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.