使用 C 修改嵌套结构的数据
Posted
技术标签:
【中文标题】使用 C 修改嵌套结构的数据【英文标题】:Modifying data of nested struct using C 【发布时间】:2018-07-21 12:58:52 【问题描述】:typedef struct node
struct node* next;
int hash;
symbol_t symbol;
node_t;
typedef struct symbol
char* name;
int addr;
symbol_t;
以上是我正在使用的两个结构的定义。我正在尝试将新的 node_t 添加到链接列表中。首先,我为node_t分配内存:
node_t* newSymbol = malloc(sizeof(node_t));
那么,node_t 应该包含一个嵌套结构(符号)。我尝试修改 node_t 中符号结构内的名称属性(字符串):
newSymbol->symbol.name = name;//name is a parameter to function I'm in
我尝试在符号嵌套结构中初始化名称和地址;但是,我收到此错误:
warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] newSymbol->symbol.name = name;
^
我尝试了多种方法来修改嵌套符号结构中的数据,但它要么抛出我上面列出的错误,要么导致分段错误。我不确定我做错了什么。提前感谢您的帮助。
【问题讨论】:
密切注意错误。它与您所指的嵌套结构无关。您正在尝试将const
指针分配给非常量指针。
【参考方案1】:
name
可能是 const char*
,symbol->name
是非常量,所以警告告诉您,通过执行 newSymbol->symbol.name = name;
您正在丢弃 const
属性,这可能不是您想要的,因为name
可能指向只读内存(如字符串文字)。
这很糟糕,因为如果你以后做这样的事情:
newSymbol->symbol.name[0] = toupper(newSymbol->symbol.name[0]);
如果newSymbol->symbol
指向一个
只读位置。
注意与
const char *txt = "Hello";
*txt = 'A';
会给你一个错误,因为const
。
解决这个问题的方法是 coderredoc 提到的:使用malloc
+
strcpy
或 strdup
(如果有)。
newSymbol->symbol.name = strdup(name);
if(newSymbol->symbol.name == NULL)
// error handling
或者如果strdup
不可用:
newSymbol->symbol.name = malloc(strlen(name) + 1);
if(newSymbol->symbol.name == NULL)
// error handling
strcpy(newSymbol->symbol.name, name);
当你有类似的功能时
void foo(const char *name);
这也是函数foo
不会修改指向的内容的提示
由name
提供,所以foo("string literal");
是安全的。因为你不能
假设name
指向可修改的内存,最好做一个副本。
【讨论】:
啊!是的,我所在的函数有给我的声明和参数。它是一个 const char*。我应该使用传递的名称来填充符号结构中的名称变量,然后修改它,这在给出 const 时看起来很奇怪。这是函数声明:int symbol_add (sym_table_t* symTab, const char* name, int addr)
@Bonfire184 a const char*
作为函数参数也暗示调用者该函数不会修改参数指向的内存,因此使用字符串字面量调用它是安全的.在这种情况下,最好复制一份const char*
。【参考方案2】:
您正在为指针分配一个局部变量的实例。这不是正确的做法,因为局部变量的生命周期将在封闭块结束时结束。所以它将是一个悬空指针,指向一些处于不确定状态的内存。
解决方案是使用strdup
,如newSymbol->symbol.name = strdup(name);
。如果您还没有 POSIX strdup
,请使用 malloc
和 memcpy
。
newSymbol->symbol.name = malloc(strlen(name)+1);
if(!newSymbol->symbol.name)
perror("malloc");
exit(1);
memcpy(newSymbol->symbol.name,name, strlen(name)+1);
此外,您在这里看到的错误是由于完全不同的原因 - 这是因为您将 const
指针分配给非常量变量,这就是编译器抱怨的原因。 (name
是一个非常量成员变量,但是发生了这个错误,从中可以推断您试图将 const
指针分配给这个成员变量)。在这种情况下,您无需从传递的参数中删除 const
限定符即可实现您想要做的事情。如何?它显示在答案中。
【讨论】:
以上是关于使用 C 修改嵌套结构的数据的主要内容,如果未能解决你的问题,请参考以下文章
React 的 setState(),嵌套结构的数据变异,为啥不直接修改状态呢?
C 语言结构体 ( 结构体中嵌套二级指针 | 为 结构体内的二级指针成员 分配内存 | 释放 结构体内的二级指针成员 内存 )