A Few Pointers on Structure Pointers

Structures aren’t really scary. Pointers are scary. Obviously, a good way to make structures more terrifying it so throw some pointers at them.

A structure whipped up from memory, referenced by its address (the pointer), is really nothing too weird. It’s not like the ** pointer notation, which is what makes so many Introduction to Programming students flee that course in a blanched panic.

The structure pointer thing starts with a structure declaration, no big deal:

struct human {
    int year;
    int month;
    int day;
    char first[32];
    char last[32];
};

But then the structure variable is declared as a pointer:

struct human *president;

Memory has to be allocated for the structure, and the structure pointer references that memory chunk’s address:

president = (struct human *)malloc(sizeof(struct human)*1);

Once created, the pointer structure’s members are referenced by using the -> operator. The dot operator could also be used, but you have to mix in pointer notation, which — believe it or not — early C programmers found obscure. (Apparently such a thing happened.) So the -> operator was concocted.

If you want to see the original structure member pointer thing operator, refer to the bottom of page 293 in my book Beginning Programming with C For Dummies. (It’s found in Chapter 20, the section “Allocating space for a structure” in case you’re reading a foreign translation.)

Here’s your sample code:

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

int main()
{
    struct human {
        int year;
        int month;
        int day;
        char first[32];
        char last[32];
    };
    struct human *president;

/* Allocate memory for the structure */
    president = (struct human *)malloc(sizeof(struct human)*1);
    if(president == NULL)
    {
        perror("Unable to allocate memory chunk");
        exit(1);
    }

/* fill structure data */
    strcpy(president->first,"George");
    strcpy(president->last,"Washington");
    president->year = 1732;
    president->month = 2;
    president->day = 22;

/* display results */
    printf("President %s %s was born on %d/%02d/%d.\n",
            president->first,
            president->last,
            president->month,
            president->day,
            president->year);

    return(0);
}

The structure human is defined at Line 7. The human structure pointer variable president is declared at Line 14. Memory is allocated for the pointer, setting its size appropriately at Line 17. Then the structure is filled and results displayed, all by using the -> operator.

Here’s the output:

President George Washington was born on 2/22/1732.

You can go one level deeper into the C language asylum by allocating storage for the structures two strings. So the structure’s definition would contain two pointers, like this:

struct human {
    int year;
    int month;
    int day;
    char *first;
    char *last;
};

The human structure could be a referenced by a pointer or as a direct variable. Either way, pointers within the structure work the same, as shown above.

To make the sample code a bit more bearable, I’ve reduced the size of the structure in the following code, which is an update to the previous example:

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

int main()
{
    struct human {
        int year;
        char *name;
    };
    struct human *president;

/* Allocate memory for the structure */
    president = (struct human *)malloc(sizeof(struct human)*1);
    if(president == NULL)
    {
        perror("Unable to allocate memory chunk");
        exit(1);
    }
/* Allocate memory for the name pointer */
    president->name = (char *)malloc(sizeof(char)*64);
    if(president->name == NULL)
    {
        perror("Unable to allocate string");
        exit(2);
    }

/* fill structure data */
    strcpy(president->name,"George Washington");
    president->year = 1732;

/* display results */
    printf("President %s was born in %d.\n",
            president->name,
            president->year);

    return(0);
}

The important thing to remember is that the name pointer, a member of the human structure, is referenced by using the format president->name. Technically that’s the address of the president structure in memory, and then the address of the name buffer. You don’t need to gussy up that variable name with asterisks or ampersands.

Here’s the program’s output:

President George Washington was born in 1732.

If president weren’t a pointer variable, then the reference would be president.name. Even though name is a pointer within the structure, it’s still referenced like any other structure member.

Most of the time you see pointers to structures happens with C language function calls. For example, the localtime() function returns the address of a tm structure. Its members must be read by using the -> operator. One of those members could be tm_zone, which is a pointer referencing the timezone name, a string. (I write “could be” because not every library implements the tm structure identically.)

The readdir() function also returns a structure’s address; the dirent structure contains members describing a directory (folder) entry. I’ll cover the dirent structure in a future Lesson.