I've looked through topics of similar kind, but didn't find a solution for my problem. I've got a struct like
typedef struct {
int number;
char *string;
} mystruct;
//Then define a pointer to the struct:
mystruct *data;
// Allocate memory:
data = malloc(sizeof(mystruct));
//Assign some number, let's say 5:
(*data).number = 5;
//So far ok, works (checked: 5 can be retrieved from the struct somewhere else) but:
strcpy((*data).string = "Hello!");
//This line fails with segmentation fault.
I don't understand why? Can somebody please explain what I'm doing wrong?
CodePudding user response:
As mentioned in the comments, the problem with your attempted strcpy
call is that your destination (the string
member of your data
) isn't a pointer to valid memory. (I am assuming that your invalid syntax, strcpy((*data).string = "Hello!")
is a typo, and that your real code has something like strcpy((*data).string, "Hello!")
– otherwise, it won't even compile, so you won't get a segmentation fault.)
There are several approaches to fix this, depending on what you actually want to happen. First, as also mentioned in the comments, you can just copy the pointer to the destination, like this1:
data->string = "Hello!";
However, this may not be what you want, because, if the source is not actually a literal, but a modifiable string, then, after that assignment, any changes to the source will also apply to your copy.
If you want a copy of the source data, you will need to allocate sufficient space for it, then call strcpy
; like this:
#include <stdlib.h> // For malloc
const char* src = "Hello!";
data->string = malloc(strlen(src) 1); // Add 1 for the required nul-terminator
strcpy(data->string, src);
However, the strdup
function2 does the job of the above malloc
and strcpy
calls in one fell swoop:
data->string = strdup("Hello!");
In each of the above two cases, be sure to call free(data->string)
when you're finished.
1 Note that you can use the "member access through pointer" (->
) operator, rather than dereferencing and then using the .
operator: data->number = 5
is equivalent to your (*data).number = 5
.
2 Some compilers/platforms may not support the strdup
function, but it is part of the ISO C Standard from C23
CodePudding user response:
I am not sure to understand this line
strcpy((*data).string = "Hello!");
Do you mean
strcpy((*data).string, "Hello!");
I believe the issue is that your struct contain a pointer char * string
that doesn't point to a valid allocated memory.
You can try multiple solutions
- Have struct with predefined size
typedef struct {
int number;
char string[100];
} mystruct;
- You can allocate memory for the string during the initialization
data = malloc(sizeof(mystruct));
data.string = malloc(sizeof(char) *100));
CodePudding user response:
As other users mentioned, you need to allocate space for the string.
I would use a flexible array member and have only one allocation for the struct and string.
typedef struct {
int number;
char string[];
} mystruct;
mystruct *create(const char *str)
{
mystruct *ms = NULL;
if(str)
{
ms = malloc(sizeof(*ms) strlen(str) 1);
if(ms)
{
strcpy(ms -> string, str);
ms -> number = 0;
}
}
return ms;
}
int main(void)
{
mystruct *ms = create("Hello");
if(ms)
{
printf("ms -> string = `%s`\n", ms -> string);
}
free(ms);
}