在另一个函数内部修改后指针数组没有改变
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
的地址正在 doubleSize
和 addItems
内更改为新创建的数组,但不在 main 函数内,即使我们传递的是指针到阵列。我在这里错过了什么?
如果你想让一个函数改变一些东西,你需要传递它的地址(或者使用一个全局地址)。
你没有,所以它不能。就这么简单。
在 main
的第一行之后,您没有修改 main
的 list
。请记住,C 仅将变量的值传递给函数(通过复制传递),并且变量的值是分配的块的地址。
如果你想让addList
能够改变main
的list
,你需要传递变量list
本身的地址(&list
).
您显然知道这个概念,因为您在 addList
中正是这样做的。您希望 doubleSize
更改 addList
的 list
,因此您将其地址传递给 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);
字符指针数组在 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
的地址正在 doubleSize
和 addItems
内更改为新创建的数组,但不在 main 函数内,即使我们传递的是指针到阵列。我在这里错过了什么?
如果你想让一个函数改变一些东西,你需要传递它的地址(或者使用一个全局地址)。
你没有,所以它不能。就这么简单。
在 main
的第一行之后,您没有修改 main
的 list
。请记住,C 仅将变量的值传递给函数(通过复制传递),并且变量的值是分配的块的地址。
如果你想让addList
能够改变main
的list
,你需要传递变量list
本身的地址(&list
).
您显然知道这个概念,因为您在 addList
中正是这样做的。您希望 doubleSize
更改 addList
的 list
,因此您将其地址传递给 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);