使用C修改嵌套结构的数据

时间:2018-02-11 04:01:44

标签: c pointers struct

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中符号结构内的name属性(字符串):

newSymbol->symbol.name = name;//name is a parameter to function I'm in

我尝试初始化符号嵌套struct中的名称和addr;但是,我收到了这个错误:

warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] newSymbol->symbol.name = name;
                                                                                                                        ^

我已尝试多种方法来修改嵌套符号结构中的数据,但它会抛出我上面列出的错误或导致分段错误。我不确定我做错了什么。提前感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

name可能是const char*symbol->name是非const,因此警告告诉您,通过执行newSymbol->symbol.name = name;,您将丢弃const可能不是你想要的属性,因为name可能指向只读内存(就像一个字符串文字)。

这很糟糕,因为如果你以后做这样的事情:

newSymbol->symbol.name[0] = toupper(newSymbol->symbol.name[0]);

如果newSymbol->symbol指向a,则可能会出现未定义的行为 只读位置。

请注意

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不会修改指向的内容 按namefoo("string literal");安全。因为你做不到 假设name指向可修改的内存,最好改为复制。

答案 1 :(得分:1)

您正在为指针分配局部变量的实例。鉴于封闭块结束时局部变量的生命周期将结束,这不是正确的做法。所以它将是一个指向一些处于不确定状态的内存的悬挂指针。

解决方案是使用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变量分配const指针,这就是编译器抱怨的原因。 (name是一个非const成员变量,但是发生了这个错误,可以推断出你试图将const指针指向这个成员变量。在此上下文中,您可以在不从传递的参数中删除const限定符的情况下实现您要执行的操作。怎么样?它显示在答案中。