我正在尝试实现一个方法,将一个给定的字符串添加到以NULL指针结尾的数组中。这是我到目前为止所得到的,但我收到一个错误,指出指针是realloc&d; d未被分配。
int main(void)
{
char **strings = init_array();
strings = add_string(strings, "one");
strings = add_string(strings, "two");
return 1;
}
char **init_array(void)
{
char **array = malloc(sizeof(char *));
array[0] = NULL;
return array;
}
char **add_string(char **array, const char *string)
{
unsigned int size = 0;
while (*array) {
size++;
array++;
}
char **newarr = (char **)realloc(array, sizeof(char *) * (size + 2));
newarr[size] = malloc(strlen(string)+1);
strcpy(newarr[size], string);
newarr[size+1] = NULL;
return newarr;
}
答案 0 :(得分:2)
问题是array++
。你必须传递realloc
返回的相同值malloc
(你的array
参数),但是你在循环中修改它,所以它只能在第一次工作(因为{{1}将立即错误)。你可以使用:
*array
其余部分保持不变。
答案 1 :(得分:1)
在while (*array)
循环中,您不仅会增加size
,还会增加array
指针本身。因此,在循环结束时size
包含数组的长度,array
指针指向最后一个(NULL
)元素。此指针从未被分配(它指向一个已分配的块),因此它不是重新分配的有效指针。 (当然这不是你打算做的。)
所以,不要在那个循环中做array++
。
答案 2 :(得分:1)
计算数组中字符串数量的循环也会使变量本身前进。您可以使用临时变量:
char **temp = array;
while (*temp)
...
或将计数分成一个函数。
顺便说一句,在使用realloc
时,您不需要投射,原因与您不使用malloc
进行投射相同。这不是一个错误,但最好是一致的。
答案 3 :(得分:1)
总结到目前为止给出的所有其他答案,添加一些最佳实践调整,相关代码应如下所示:
char **add_string(char **array, const char *string)
{
char ** newarr;
size_t size = 0;
assert (NULL != string); /* Need to include assert.h */
if (NULL != array)
{
while (NULL != array[size])
{
++size; /* Just count, do not touch the pointer value allocated. */
}
}
newarr = realloc(array, (size + 2) * sizeof *newarr);
if (NULL == newarr) /* Test the outcome of reallocation. */
{
perror("realloc() failed"); /* Need to include stdio.h */
return NULL;
}
newarr[size] = malloc(strlen(string) + 1);
if (NULL == newarr[size])
{
perror("malloc() failed"); /* Need to include stdio.h */
/* Might want to clean up here and indicate the failure to the
caller by returning NULL. */
}
else
{
strcpy(newarr[size], string);
}
newarr[size+1] = NULL;
return newarr;
}
甚至更严格:
char **add_string(char **array, const char *string)
{
assert (NULL != string); /* Need to include assert.h */
{
size_t size = 0;
if (NULL != array)
{
while (NULL != array[size])
{
++size; /* Just count, do not touch the pointer value allocated. */
}
}
{
char ** newarr = realloc(array, (size + 2) * sizeof *newarr);
if (NULL == newarr)
{
perror("realloc() failed"); /* Need to include stdio.h */
}
if (NULL != newarr)
{
newarr[size] = malloc(strlen(string) + 1);
if (NULL == newarr[size])
{
perror("malloc() failed"); /* Need to include stdio.h */
}
else
{
strcpy(newarr[size], string);
}
newarr[size+1] = NULL;
}
return newarr;
}
}
}
答案 4 :(得分:0)
最简单的方法是保留初始数组指针并使用它来重新分配内存。
int main(void)
{
char **strings = init_array();
strings = add_string(strings, "one");
strings = add_string(strings, "two");
return 1;
}
char **init_array(void)
{
char **array = malloc(sizeof(char *));
array[0] = NULL;
return array;
}
char **add_string(char **array, const char *string)
{
char** cache = array;
unsigned int size = 0;
while (*array) {
size++;
array++;
}
char **newarr = (char **)realloc(cache, sizeof(char *) * (size + 2));
newarr[size] = malloc(strlen(string)+1);
strcpy(newarr[size], string);
newarr[size+1] = NULL;
return newarr;
}
另一个注意事项 - 主要功能应该在成功时返回0。