Reputation: 83
Given the following C code:
#include <stdio.h>
#include <string.h>
typedef struct a {
char name[10];
} a;
typedef struct b {
char name[10];
} b;
void copy(a *source, b *destination) {
strcpy(destination->name, source->name);
}
This main function below runs successfully:
int main() {
a first;
b second;
strcpy(first.name, "hello");
copy(&first, &second);
printf("%s\n", second.name);
printf("Finished\n");
return 1;
}
While this main function results in a segmentation fault:
int main() {
a *first;
b *second;
strcpy(first->name, "hello");
copy(first, second);
printf("%s\n", second->name);
printf("Finished\n");
return 1;
}
From my understanding of C, both implementations should run identically. What are the differences between the implementations and how can I adjust the second implementation to successfully run to completion?
Upvotes: 0
Views: 43
Reputation: 311078
The program are not identical because in the second program the declared pointers
a *first;
b *second;
are not initialized, have indeterminate values and do not point tfo valid objects of the types a and b.
You have to define objects of the types a and be to which the pointers will point to.
For this purpose you could use for example the compound literal.
Here is a demonstrative program
#include <stdio.h>
#include <string.h>
typedef struct a {
char name[10];
} a;
typedef struct b {
char name[10];
} b;
void copy(a *source, b *destination) {
strcpy(destination->name, source->name);
}
int main(void)
{
a *first = &( a ){ 0 };
b *second = &( b ) { 0 };
strcpy(first->name, "hello");
copy(first, second);
printf("%s\n", second->name);
printf("Finished\n");
return 0;
}
The program output is
hello
Finished
Upvotes: 0
Reputation: 1251
In the second code, you are only creating to pointer on a
and b
structs, but you aren't allocating memory for them..
You have to use the following code to properly allocate memory for your structs :
a *first = (struct a*)malloc(sizeof(struct a));
b *second = (struct b*)malloc(sizeof(struct b));
Upvotes: 1
Reputation: 15586
They don't run identically because you don't allocate memory for first
and second
in the second example. To do that, you can allocate them using malloc
:
a *first = malloc(sizeof(*first));
b *second = malloc(sizeof(*second));
If you allocate using malloc
, make sure to check if the pointers are NULL
before using them. If they are NULL
, you should return an error or (in main
) exit the program. In a non-trivial program, you should also call free
on these pointers after you're done using them.
Alternatively, you can allocate them on the stack:
a first[1];
b second[1];
This does not require you to call free
. I recommend this form.
Upvotes: 3