typedef struct node {
struct node* next;
int hash;
symbol_t symbol;
} node_t;
typedef struct symbol {
char* name;
int addr;
} symbol_t;
Above are the definitions of two structs I am using. I'm trying to add a new node_t to a linked list. First, I allocate memory for the node_t:
node_t* newSymbol = malloc(sizeof(node_t));
Then, the node_t should contain a nested struct (symbol). I try to modify the name property (string) inside the symbol struct that's in the node_t:
newSymbol->symbol.name = name;//name is a parameter to function I'm in
I try to initialize the name and the addr inside of the symbol nested struct; however, I am getting this error:
warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] newSymbol->symbol.name = name;
^
I've tried multiple ways to modify data in the nested symbol struct, but it either throws the error I listed above or results in a segmentation fault. I'm not sure what I'm doing wrong. Thanks in advance for any help.
name
is probably a const char*
, symbol->name
is a non-const, so the warning tells you that by doing newSymbol->symbol.name = name;
you are throwing away the const
property and that might not be what you want, as name
may be pointing into read-only memory (like a string literal).
This is bad, because if you later do something like this:
newSymbol->symbol.name[0] = toupper(newSymbol->symbol.name[0]);
this could end up with undefined behaviour if newSymbol->symbol
points to a read-only location.
Note that with
const char *txt = "Hello";
*txt = 'A';
would give you an error, because of the const
.
The solution to this would be the one mentioned by coderredoc: use malloc
+ strcpy
or strdup
if available.
newSymbol->symbol.name = strdup(name);
if(newSymbol->symbol.name == NULL)
{
// error handling
}
or if strdup
is not available:
newSymbol->symbol.name = malloc(strlen(name) + 1);
if(newSymbol->symbol.name == NULL)
{
// error handling
}
strcpy(newSymbol->symbol.name, name);
When you have a function like
void foo(const char *name);
this is also a hint that the function foo
won't modify the content pointed to by name
, so it's safe to do foo("string literal");
. Because you cannot assume that name
points to modifiable memory, it's best to do a copy instead.
You are assigning to a pointer an instance of a local variable. This is not the right thing to do given that local variables lifetime will end when the enclosing block ends. So it will be a dangling pointer to some memory which is in indeterminate state.
Solution is to use strdup
like newSymbol->symbol.name = strdup(name);
. In case you have not POSIX strdup
make one using malloc
and memcpy
.
newSymbol->symbol.name = malloc(strlen(name)+1);
if(!newSymbol->symbol.name){
perror("malloc");
exit(1);
}
memcpy(newSymbol->symbol.name,name, strlen(name)+1);
Also here the error you see is due to completely different reason - it is because you are assigning a const
pointer to a non-const variable which is why compiler complained. ( name
is a non-const member variable but this error occurred from which it can be inferred that you tried to assign const
pointer to this member variable). In this context you can achieve what you are trying to do without removing the const
qualifier from the passed argument. How? It is shown in the answer.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.