问题描述
main
中的char指针数组未更改。
情况如下:在main
中,声明了一个char指针数组,并为其分配了内存。 main
调用另一个名为AddItems
的函数,该函数将项目添加到列表中,并且该函数调用doubleSize
以使列表大小加倍。在AddItems
中添加新项目并使数组大小增加一倍,一切工作都按预期进行。但是,问题在于,AddItems
返回时,即使我们正在传递指向列表的指针,main仍然具有列表的较旧副本。
这是MWE:
#define INITIAL_SIZE (4)
int main(void)
{
char **list = (char **) malloc(INITIAL_SIZE * sizeof(char *));
int list_size = INITIAL_SIZE;
for (int i = 0; i < list_size; i++) {
list[i] = (char *) malloc(5 * sizeof(char));
strcpy(list[i],"jane");
}
printf("main--> address of list: %p\n",list);
/* output = 0x7fc15e402b90 */
addItems(list,&list_size);
/* After adding items: */
printf("main--> address of list: %p\n",list);
/* output = 0x7fc15e402b90 (no change) */
return 0;
}
以下是其他两个示例函数:
void doubleSize(char ***list,int *current_size)
{
char **newList = (char**) malloc(*current_size * 2 * sizeof(char*));
for (int i = 0; i < *current_size; i++)
newList[i] = (*list)[i];
free(*list);
*list = newList;
*current_size = (*current_size) * 2;
}
void addItems(char **list,int * size)
{
printf("Before doubling: %p\n",list);
/* Output: 0x7fc15e402b90 */
/* Double the size */
doubleSize(&list,size);
printf("After doubling: %p\n",list);
/* Output: 0x7fc15e402be0 */
}
list
的地址将更改为doubleSize
内以及addItems
内的新创建的数组,但不会更改为main函数内的数组,即使我们正在传递指向数组。我在这里想念什么?
解决方法
您还可以通过修改addItems
char** addItems(char **list,int * size)
{
printf("Before doubling: %p\n",list);
/* Output: 0x7fc15e402b90 */
/* Double the size */
doubleSize(&list,size);
printf("After doubling: %p\n",list);
/* Output: 0x7fc15e402be0 */
return list;
}
来自main
的呼叫应为:
list = addItems(list,&list_size);
,
如果您希望函数更改某些内容,则需要传递其地址(或使用全局地址)。
您没有,所以没有。就这么简单。
在main
第一行之后的任何时候都不得修改main
的{{1}}。请记住,C仅将变量的值传递给函数(通过副本传递),并且变量的值是分配的块的地址。
如果您希望list
能够更改addList
的{{1}},则需要传递变量main
本身的地址({{1} }。
您显然已经意识到了这个概念,因为您在list
中确实做到了。您希望list
更改&list
的{{1}},因此您将其地址传递给了addList
。
提示:最好在doubleSize
中使用addList
。
list
由于我们忽略了内存不足错误,因此以上内容简化为
doubleSize