c-在另一个函数中被修改后不发生变化的指针数组



main中没有更改字符指针数组。情况如下:在main内部,声明了一个字符指针数组,并为其分配了内存。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: %pn", list); 
/* output = 0x7fc15e402b90 */
addItems(list, &list_size);
/* After adding items: */
printf("main--> address of list: %pn", 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: %pn", list);
/* Output: 0x7fc15e402b90 */
/* Double the size */
doubleSize(&list, size);
printf("After doubling: %pn", list);
/* Output: 0x7fc15e402be0 */
}

list的地址正在更改为doubleSize内部和addItems内部新创建的数组,但不在主函数内部,即使我们正在传递指向数组的指针。我在这里错过了什么?

您也可以通过修改addItems来尝试如下操作

char** addItems(char **list, int * size)
{
printf("Before doubling: %pn", list);
/* Output: 0x7fc15e402b90 */
/* Double the size */
doubleSize(&list, size);
printf("After doubling: %pn", list);
/* Output: 0x7fc15e402be0 */
return list;
}

来自main的呼叫应该是:

list = addItems(list, &list_size);

如果希望函数更改某些内容,则需要传递其地址(或使用全局地址(。

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


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;
}

由于我们忽略了内存不足的错误,以上简化为

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

最新更新