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

使用C修改嵌套结构的数据,c,pointers,struct,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* newSymbol = mall

上面是我正在使用的两个结构的定义。我正在尝试将新节点添加到链接列表中。首先,我为节点分配内存:

typedef struct node {
  struct node* next;     
  int          hash;     
  symbol_t     symbol;   
} node_t;

typedef struct symbol {
  char* name; 
  int   addr; 
} symbol_t;
node_t* newSymbol = malloc(sizeof(node_t));
然后,节点应包含嵌套的结构符号。我尝试修改节点中的符号结构中的name属性字符串:

typedef struct node {
  struct node* next;     
  int          hash;     
  symbol_t     symbol;   
} node_t;

typedef struct symbol {
  char* name; 
  int   addr; 
} symbol_t;
node_t* newSymbol = malloc(sizeof(node_t));
我尝试初始化符号嵌套结构内部的名称和地址;但是,我遇到了以下错误:

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

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

您正在为指针指定局部变量的实例。考虑到局部变量的生存期将在封闭块结束时结束,这不是正确的做法。因此,它将是一个指向某个处于不确定状态的内存的悬空指针

解决方案是像newSymbol->symbol.name=strdupname;一样使用strdup;。如果您没有POSIX标准,请使用malloc和memcpy创建一个标准

在这里,您看到的错误是由于完全不同的原因造成的-这是因为您正在将常量指针分配给非常量变量,这就是编译器抱怨的原因。name是一个非常量成员变量,但发生了此错误,由此可以推断您试图将常量指针分配给此成员变量。在此上下文中,您可以在不从传递的参数中删除const限定符的情况下实现所要做的事情。怎样答案中显示了它。

name可能是常量字符*,symbol->name是非常量,因此警告告诉您,通过执行newSymbol->symbol.name=name;您正在丢弃const属性,而这可能不是您想要的,因为name可能像字符串文字一样指向只读内存

这是不好的,因为如果你以后做这样的事情:

newSymbol->symbol.name = malloc(strlen(name)+1);
if(!newSymbol->symbol.name){
    perror("malloc");
    exit(1);
}
memcpy(newSymbol->symbol.name,name, strlen(name)+1);
如果newSymbol->symbol指向 只读位置

请注意

newSymbol->symbol.name[0] = toupper(newSymbol->symbol.name[0]);
会给你一个错误,因为常数

解决这个问题的方法是coderredoc提到的:使用malloc+ strcpy或strdup(如果可用)

const char *txt = "Hello";
*txt = 'A';
或者如果strdup不可用:

newSymbol->symbol.name = strdup(name);
if(newSymbol->symbol.name == NULL)
{
    // error handling
}
当你有一个函数,比如

newSymbol->symbol.name = malloc(strlen(name) + 1);
if(newSymbol->symbol.name == NULL)
{
    // error handling
}

strcpy(newSymbol->symbol.name, name);
这也是一个提示,函数foo不会修改指向的内容 通过名称,因此可以安全地执行foostring literal;。因为你不能
假设名称指向可修改内存,最好改为复制。

请密切注意错误。它与您所引用的嵌套结构无关。你试图将常量指针分配给非常量指针。啊!是的,我所在的函数已经给了我声明和参数。它是一个常量字符*。我应该使用传递的名称来填充symbol结构中的name变量,然后修改它,这在给定const时显得很奇怪。下面是函数声明:int symbol\u add sym\u table\u t*symTab,const char*name,intaddr@Bonfire184作为函数参数的const char*也提示调用方函数不会修改参数指向的内存,因此使用字符串文本调用它是安全的。在这种情况下,最好复制const char*。