broun
broun

Reputation: 2593

char array to a string inside a struct

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:

Attempt: 1

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';

Attempt: 2

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

Answers (4)

kmcguire
kmcguire

Reputation: 904

You can do it two ways:

Assign the pointer to the character array

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");

Allocate memory and copy the character array

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

P.P
P.P

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

Vlad
Vlad

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:

  1. allocate char_arr on heap and use my_struct.my_string = char_arr, or
  2. allocate my_string on heap and use strcpy(my_struct.my_string, char_arr)
  3. use 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

Mahesh
Mahesh

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

Related Questions