如果这个问题是基本问题,我深表歉意 - 我是 C 的新手,仍然有点不确定在内存中如何处理数组,而不是指针(指向数组)。 (例如,如前所述 here 。)
以下片段与我遇到的问题类似。假设我在 :
中有这样定义的结构 List 和 Sublisttypedef struct {
char items[MAX_NUM_ITEMS][MAX_ITEM_LENGTH];
int num_items;
} Sublist;
typedef struct {
Sublist sublists[MAX_NUM_SUBLISTS];
int num_sublists;
} List;
我有一个函数,它接受一个指向列表的指针,希望对其进行修改。例如
void add_item_to_sublist(List *list, int sublist_number, const char *new_item) {...
目标是(如果有效,我有点掩饰)将新项目附加到指定的子列表。
有一次我基本上做了以下事情:
Sublist current = list->sublists[sublist_number];
然后执行将new_item附加到current的操作。也许你并不感到惊讶,但这失败了。在试图找出问题所在时,我想到问题可能与按值传递范式有关,所以我尝试了
Sublist *current = &list->sublists[sublist_number];
相反 - 这有效。
所以这是我的困惑。一方面,我知道存在按值传递问题,因此如果 current 仅存在于我的函数的框架中,那么显然它会在函数终止后与我的修改一起被清除。但另一方面,我认为结构赋值是在内存中,即“引用副本”情况 - 所以我最初认为对当前(第一个版本)的任何更改也会自动更改子列表 [sublist_number]。
有人可以帮助我理解我的错误吗?
最佳答案
该问题与按值传递无关,后者与传递给函数的参数有关(这可能会导致类似的问题),而是您正在分配给 Sublist
变量的事实。
Sublist current;
这是一个语义问题。 current
是 Sublist
的实例,不是某物的别名,也不是指针,而是整个 Sublist
。当你分配给它时:
Sublist current = list->sublists[sublist_number];
您正在为一个 Sublist
实例分配另一个实例,该实例是通过将整个内容复制到目标而获得的。发生了什么。
然后您修改current
,但您修改的是原始文件的副本。您可以将其重新分配回去,例如:
Sublist current = list->sublists[sublist_number];
/* alter current */
list->sublists[sublist_number] = current;
但这没有意义,因为您实际上并不需要副本,但您想修改原始数据。
这就是您使用 *
的原因,因此现在 current 是一个 Sublist*
变量。它不是 Sublist
的实例,而是指向(希望)Sublist
的现有实例的指针。现在通过 current
完成的每个修改都反射(reflect)到原始数据,因为没有另一个实例。
关于c - 内存中的结构赋值和持久化(C语言),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44641916/