在另一个函数内部修改后指针数组没有改变

Array of pointers not changing after getting modified inside another function

字符指针数组在 main 中未更改。 情况如下:在 main 内,声明了一个字符指针数组,并为其分配了内存。 main 调用另一个名为 AddItems 的函数,该函数将项目添加到列表中,该函数调用 doubleSize 将列表的大小加倍。在 AddItems 中添加新项目并将数组的大小加倍方面,一切都按预期工作。然而,问题是当 AddItems returns 时,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 的地址正在 doubleSizeaddItems 内更改为新创建的数组,但不在 main 函数内,即使我们传递的是指针到阵列。我在这里错过了什么?

如果你想让一个函数改变一些东西,你需要传递它的地址(或者使用一个全局地址)。

你没有,所以它不能。就这么简单。


main 的第一行之后,您没有修改 mainlist。请记住,C 仅将变量的值传递给函数(通过复制传递),并且变量的值是分配的块的地址。

如果你想让addList能够改变mainlist,你需要传递变量list本身的地址(&list).

您显然知道这个概念,因为您在 addList 中正是这样做的。您希望 doubleSize 更改 addListlist,因此您将其地址传递给 doubleSize


提示:最好在doubleSize中使用realloc

void doubleSize(char ***list, size_t *size) {
    size_t new_size = *size * 2;
    char **new_list = realloc(*list, new_size);
    if (!new_list) [
        // Ignoring out-of-memory errors.
    }

    *list = new_list;
    *size = new_size;
}

由于我们忽略了 out-of-memory 错误,以上简化为

void doubleSize(char ***list, size_t *size) {
    *list = realloc(*list, ( *size *= 2 ));
}

您也可以尝试如下修改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);