Reputation: 2593
I have an array of 4 characters, for example:
char char_array[10];
char_arr[0] = 'a';
char_arr[1] = 'b';
char_arr[2] = 'c';
char_arr[3] = 'd';
char_arr[4] = '\0';
and I have a structure:
typedef struct{
int my_int;
char *my_string;
} my_struct_t;
my_struct_t my_struct;
my_struct.my_string = malloc(10);
I want to assign the char array to the string my_struct.my_string
How to I do this? I tried the following:
my_struct.my_string = malloc(10)
my_struct.my_string[0] = char_arr[2];
my_struct.my_string[1] = char_arr[2];
my_struct.my_string[2] = '\0';
strcpy(my_struct.my_string, char_arr);
Both fail i.e the destination is empty (compilation succeeds). Why does the above fail and how can I overcome this?
I have both the struct and the char array in stack since I don't want these once I exit the function. I have allocated memory to my_struct.my_string
before assigning it.
Upvotes: 2
Views: 3115
Reputation: 904
You can do it two ways:
Once the function exits the char_array[10] which the pointer points to will become invalid. The compiler will produce no error, but eventually the program will likely crash because you will overwrite data for another function, or read the wrong data because another function overwrote it with something else. You should google about how the stack works on your computer architecture.
char char_array[10];
my_struct_t var;
var.my_string = &array[0];
var.my_string[3] = 'a';
if (var.my_string[0] == char_array[0])
printf("See, changes using the pointer effect char_array.\n");
else
printf("This will never happen.\n");
I used for loops to help make it easier to understand exactly how it works. Once the current function exits the pointer will still point to valid memory if you happen to keep it around somehow.
char char_array[10];
my_struct_t var;
int l;
char_array[0] = 'a';
char_array[1] = 0;
// l = strlen(&char_array[0])
for (l = 0; char_array[l] != 0; ++l);
var.my_string = (char*)malloc(sizeof(char) * l);
// strcpy(var.my_string, &char_array[0]);
for (l = 0; char_array[l] != 0; ++l)
var.my_string[l] = char_array[l];
var.my_string[0] = 'a';
if (var.my_string[0] != char_array[0])
printf("See, changes using the pointer DO NOT effect char_array.\n");
else
printf("This will never happen.\n");
Upvotes: 1
Reputation: 121347
You need to allocate memory for my_string before storing char_arr into it.
If you have allocated memory, it should work. This is same as your code (without typedef) and it works fine:
struct my{ int my_int; char *my_string; }p;
int main()
{
char char_arr[5];
strcpy(char_arr, "abcd");
p.my_string = (char*) malloc(5);
strcpy(p.my_string, char_arr);
print_string(); //
return 0;
}
print_string()
{
printf("%s",p.my_string);
}
Upvotes: 1
Reputation: 35584
I assume, you allocate your char_arr
on stack, therefore the 1st approach fails. The 2nd approach fails if you don't allocate the memory for the destination. Some of the correct ways are:
char_arr
on heap and use my_struct.my_string = char_arr
, ormy_string
on heap and use strcpy(my_struct.my_string, char_arr)
strdup
, if your compiler supports it.Longer explanation:
You should understand the basics of C memory management. In C, string is just a pointer to a memory chunk. Copying that pointer won't prevent the stack-allocated string to disappear. So, you have to allocate the memory anyway in heap. In order to do this, you either allocate char_arr
there (which makes the 1st method valid), or you let the char_arr
live on stack, but then you cannot keep the reference to its data (it's going to be destroyed after your current function exits), you need to copy the data to a heap-allocated string. This can be done either manually (with malloc
), or using strdup
.
Upvotes: 1
Reputation: 34615
If char_arr
is of char[N]
type, then malloc
array of sizeof(char_arr)/sizeof(char_arr[0])
to my_struct.my_string
. And then copy value at each index using strcpy
. Finally free
when done.
Upvotes: 2