David542
David542

Reputation: 110163

Possible to initialize/assign a struct pointer?

Let's say I have the following struct and two versions to initialize it:

#include <stdio.h>

typedef struct Car *CarPtr;
typedef struct Car {
        const char*     name;
        unsigned int    price;
} Car;

int main(void) {

    Car ford = {
        .name = "Ford F-150",
        .price = 25000
    };
    print_struct(&ford);

    // is this possible to do in a single assignment?
    CarPtr jeep = {
        .name = "Jeep",
        .price = 40000
    };
    print_struct(jeep);

}

Is the second version possible to do directly? Or do I need to do something along the lines of:

CarPtr jeep;
jeep->name = "Jeep";
jeep->price = 40000;

Or what's the proper way to initialize the CarPtr type directly?

Upvotes: 1

Views: 171

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 310970

CarPtr is a pointer (scalar object) that may be initialized by a braced list containing only a single expression.

So this initialization

CarPtr jeep = {
    .name = "Jeep",
    .price = 40000
};

is incorrect.

Something similar to what you are trying to achieve looks with using a compound literal the following way.

#include <stdio.h>

typedef struct Car *CarPtr;
typedef struct Car {
        const char*     name;
        unsigned int    price;
} Car;

int main( void )
{
    CarPtr jeep = &( Car ){ .name = "Jeep", .price = 40000 };
    
    printf( "%s - %u\n", jeep->name, jeep->price );
}

The program output is

Jeep - 40000

Pay attention to that you shall not free the pointed object by using the standard function free because the compound literal has automatic storage duration in this context.

Upvotes: 1

Eric Postpischil
Eric Postpischil

Reputation: 222650

Pointers, other than null pointers, need to point to objects that exist (which can be memory that has been allocated but not yet filled in). You can define a pointer and initialize it to an object you create at the same time, using a compound literal:

CarPtr jeep = & (Car) { .name = "Jeep", .price = 40000 };

This is a special syntax, with the type name in parentheses followed by braces containing initializers just as in a definition. (It is not a cast.)

You can also pass a compound literal or its address directly to a function:

print_struct(& (Car) { .name = "Jeep", .price = 40000 });

However, this has limited uses, as, if this is done inside a function, the object is temporary; its lifetime lasts only as long as the current function execution lasts. You can use a compound literal outside a function, and then it lasts for all of program execution. You should have a general understanding and awareness of the properties of compound literals before using them.

Upvotes: 2

Related Questions