listcomps4thewin
listcomps4thewin

Reputation: 83

Differences between Instance Creation and Pointer to Instance Creation in C?

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

Answers (3)

Vlad from Moscow
Vlad from Moscow

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

cocool97
cocool97

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

S.S. Anne
S.S. Anne

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

Related Questions