Prev NEXT

The Basics of C Programming

Pointers to Structures

It is possible to create a pointer to almost any type in C, including user-defined types. It is extremely common to create pointers to structures. An example is shown below:

typedef struct
{
	char name[21];
	char city[21];
	char state[3];
} Rec;
typedef Rec *RecPointer;

RecPointer r;
r = (RecPointer)malloc(sizeof(Rec));

The pointer r is a pointer to a structure. Please note the fact that r is a pointer, and therefore takes four bytes of memory just like any other pointer. However, the malloc statement allocates 45 bytes of memory from the heap. *r is a structure just like any other structure of type Rec. The following code shows typical uses of the pointer variable:

Advertisement

strcpy((*r).name, "Leigh");
strcpy((*r).city, "Raleigh");
strcpy((*r).state, "NC");
printf("%s\n", (*r).city);
free(r);

You deal with *r just like a normal structure variable, but you have to be careful with the precedence of operators in C. If you were to leave off the parenthesis around *r the code would not compile because the "." operator has a higher precedence than the "*" operator. Because it gets tedious to type so many parentheses when working with pointers to structures, C includes a shorthand notation that does exactly the same thing:

strcpy(r->name, "Leigh");

The r-> notation is exactly equivalent to (*r)., but takes two fewer characters.

Pointers to Arrays

It is also possible to create pointers to arrays, as shown below:

int *p;
	int i;

	p = (int *)malloc(sizeof(int[10]));
	for (i=0; i<10; i++)
		p[i] = 0;
	free(p);

or:

	int *p;
	int i;

	p = (int *)malloc(sizeof(int[10]));
	for (i=0; i<10; i++)
		*(p+i) = 0;
	free(p);

Note that when you create a pointer to an integer array, you simply create a normal pointer to int. The call to malloc allocates an array of whatever size you desire, and the pointer points to that array's first element. You can either index through the array pointed to by p using normal array indexing, or you can do it using pointer arithmetic. C sees both forms as equivalent.

This particular technique is extremely useful when working with strings. It lets you allocate enough storage to exactly hold a string of a particular size.

Arrays of Pointers

Sometimes a great deal of space can be saved, or certain memory-intensive problems can be solved, by declaring an array of pointers. In the example code below, an array of 10 pointers to structures is declared, instead of declaring an array of structures. If an array of the structures had been created instead, 243 * 10 = 2,430 bytes would have been required for the array. Using the array of pointers allows the array to take up minimal space until the actual records are allocated with malloc statements. The code below simply allocates one record, places a value in it, and disposes of the record to demonstrate the process:

	typedef struct
	{
		char s1[81];
		char s2[81];
		char s3[81];
	} Rec;
	Rec *a[10];

	a[0] = (Rec *)malloc(sizeof(Rec));
	strcpy(a[0]->s1, "hello");
	free(a[0]);

Structures Containing Pointers

Structures can contain pointers, as shown below:

typedef struct
	{
		char name[21];
		char city[21];
		char phone[21];
		char *comment;
	} Addr;
	Addr s;
	char comm[100];

	gets(s.name, 20);
	gets(s.city, 20);
	gets(s.phone, 20);
	gets(comm, 100);
	s.comment =
     (char *)malloc(sizeof(char[strlen(comm)+1]));
	strcpy(s.comment, comm);

This technique is useful when only some records actually contained a comment in the comment field. If there is no comment for the record, then the comment field would consist only of a pointer (4 bytes). Those records having a comment then allocate exactly enough space to hold the comment string, based on the length of the string typed by the user.