'Designated Initialiser on struct causes segfault in strcpy and realloc
I'm using WSL Ubuntu-20.04 LTS and compiling with gcc.
I'm preparing some examples to teach the basics of C to CS Students and as I was reading about designated Initialisers, the following bit of code caused errors,
typedef enum {male, female} sexe;
struct human_t {
char * name;
char * title;
sexe gender;
};
struct human_t steve = {.name = "Steve",
.title = "Mr.",
.gender = male
};
strcpy(steve.name, "AA");
And reading the manual on strcpy the destination buffer being of larger size than "AA" I'm simply at a loss as to why this doesn't work.
I also observed the following :
struct human_t steve = {.name = "Steve",
.title = "Mr.",
.gender = male
};
char * new_name = "Gobeldydukeryboo";
realloc(steve.name, strlen(new_name));
strcpy(steve.name, new_name);
And this returns the error realloc(): invalid pointer.
Reading the manual on realloc the pointer must have been returned by a malloc call for it to work.
I'm having a feeling that designated initialisation does not call malloc, which would explain why realloc fails, it doesn't, however, explain why strcpy fails.
What's going on here ?
Solution 1:[1]
In this declaration
struct human_t steve = {.name = "Steve",
.title = "Mr.",
.gender = male
};
you initialized the pointer name with the address of the first character of the string literal "Steve".
Then in this statement
strcpy(steve.name, "AA");
you was trying to change the string literal.
Any attempt to change a string literal results in undefined behavior.
Instead you could just write
steve.name = "AA";
After that the pointer name will point to the string literal "AA".
In this statement
realloc(steve.name, strlen(new_name));
you are trying to reallocate the memory occupied by a string literal that has static storage duration. But you may reallocate only memory that was previously allocated dynamically. Moreover in general you need to assign to a pointer the returned address of a call of realloc. Otherwise the address of the reallocated memory will be lost and you will have a memory leak.
Either declare the data member name as a character array as for example
struct human_t {
char name[10[;
char * title;
sexe gender;
};
Or always allocate dynamically a memory to store there a string as for example
struct human_t steve = {.name = malloc( 10 ),
.title = "Mr.",
.gender = male
};
strcpy( steve.name, "Steve" );
The same problem exists with another data member title.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
