在另一个函数中修改后,指针数组未更改

问题描述

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