Pointers on Pointers in Structures

Structures are the complex variable type in C, allowing you to craft data-rich units for storing and retrieving all sorts of interesting information. They’re fun! But like asterisks falling as snowflakes, sprinkle some pointers into a structure and you can get into trouble fast.

It comes down to a battle between the . and -> operators, both of which reference structure members. The . operator is the one that you’re glad to use. The -> implies that a pointer lurks somewhere in the structure. But where?

This code employs a structure variable to store a person’s name. It contains two members, char arrays first and last:

#include <stdio.h>
#include <string.h>

int main()
{
    struct name {
        char first[24];
        char last[24];
    };
    struct name me;

    strcpy(me.first,"Dan");
    strcpy(me.last,"Gookin");

    printf("Hello, %s %s!\n",
            me.first,
            me.last);

    return(0);
}

Lines 12 and 13 copy constant strings into the array; both use the . member operator. Here’s the output:

Hello, Dan Gookin!

Now hide behind your chair. For a pointer version of the code, you have several options: pointer structure, pointer members, or both pointer structure and pointer members.

The first option is to make the structure itself a pointer:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    struct name {
        char first[24];
        char last[24];
    };
    struct name *me;

    me = (struct name *)malloc(1 * sizeof(struct name));
    if( me==NULL )
    {
        puts("Unable to allocate memory");
        return(1);
    }

    strcpy(me->first,"Dan");
    strcpy(me->last,"Gookin");

    printf("Hello, %s %s!\n",
            me->first,
            me->last);

    return(0);
}

The name structure pointer me is declared at Line 11. It’s just a pointer, a storage container for a memory location.

At Line 13, the malloc() function sets aside space for the name structure and saves that location in me. Because me is a pointer, the -> operator must be used to address its members. You see that operator in Lines 20, 21, 24, and 25.

The program’s output is the same as the first example.

Now consider this code, where the members are pointers, but the structure isn’t:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    struct name {
        char *first;
        char *last;
    };
    struct name me;

    me.first = (char *)malloc( sizeof(char) * 24 );
    me.last = (char *)malloc( sizeof(char) * 24 );
    if( me.first==NULL || me.last==NULL)
    {
        puts("Unable to allocate memory");
        return(1);
    }

    strcpy(me.first,"Dan");
    strcpy(me.last,"Gookin");

    printf("Hello, %s %s!\n",
            me.first,
            me.last);

    return(0);
}

The malloc() statements at line 13 and 14 assigns storage to the first and last pointers. Because the structure itself isn’t a pointer, the standard member operator (.) is used.

Finally, here’s a beast:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    struct name {
        char *first;
        char *last;
    };
    struct name *me;

    me = (struct name *)malloc( sizeof(struct name) * 1);
    if( me==NULL )
    {
        puts("Unable to allocate memory");
        return(1);
    }
    me->first = (char *)malloc( sizeof(char) * 24 );
    me->last = (char *)malloc( sizeof(char) * 24 );
    if( me->first==NULL || me->last==NULL)
    {
        puts("Unable to allocate memory");
        return(1);
    }

    strcpy(me->first,"Dan");
    strcpy(me->last,"Gookin");

    printf("Hello, %s %s!\n",
            me->first,
            me->last);

    return(0);
}

Everything’s a pointer!

The me structure, as well as its members, must be allocated storage. The pointer me is done first, otherwise memory can’t be allocated for its members. The -> member operator is required because structure me is a pointer — and that’s the only reason. If only the members were pointers, as shown in the earlier example, you use the standard . member operator.

I hope these examples help you to understand how pointers operate within a structure. The knots get tighter when you mix structures within structures along with pointers. That dangerous ground I cover in next week’s Lesson.

Leave a Reply