使用 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 + strcpystrdup(如果有)。

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,请使用 mallocmemcpy

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 修改嵌套结构的数据的主要内容,如果未能解决你的问题,请参考以下文章

C qsort 嵌套结构数组

C:如果调用顺序改变,使用结构的嵌套函数会破坏程序

React 的 setState(),嵌套结构的数据变异,为啥不直接修改状态呢?

c语言结构体类型数组长度

C 语言结构体 ( 结构体中嵌套二级指针 | 为 结构体内的二级指针成员 分配内存 | 释放 结构体内的二级指针成员 内存 )

在Python中使用ElementTree API插入xml元素作为嵌套元素。