c - 内存中的结构赋值和持久化(C语言)

标签 c arrays struct

如果这个问题是基本问题,我深表歉意 - 我是 C 的新手,仍然有点不确定在内存中如何处理数组,而不是指针(指向数组)。 (例如,如前所述 here 。)

以下片段与我遇到的问题类似。假设我在 :

中有这样定义的结构 List 和 Sublist
typedef 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;

这是一个语义问题。 currentSublist 的实例,不是某物的别名,也不是指针,而是整个 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/

相关文章:

检查点是在圆内还是在圆外(仅使用结构体实现)

python - 如何转置数据框

c - GArray 未按预期在初始化时清除

c++ - 使用结构/遗传算法

performance - 声明 struct 字段的类型与 Julia 中的结构本身的类型相同

c++ - 扩展 Lua : check number of parameters passed to a function

c - 将 C 中的子数组传递给一维数组函数

java - 如何比较字符串数组和字符数组

c - C 结构中的数组,指向常量的指针

多次更改函数中数组的值