指针的指针
创建指向指针的指针是可能且通常有用的。这种技术有时被称为句柄,在操作系统希望能够自由移动堆上的内存块的特定情况下非常有用。以下示例演示了一个指向指针的指针
int **p;
int *q;
p = (int **)malloc(sizeof(int *));
*p = (int *)malloc(sizeof(int));
**p = 12;
q = *p;
printf("%d\n", *q);
free(q);
free(p);
Windows 和 Mac OS 使用这种结构来允许堆上的内存整理。程序管理指针 p,而操作系统管理指针 *p。由于操作系统管理 *p,因此 *p 指向的内存块 (**p) 可以移动,并且 *p 可以更改以反映移动,而不会影响使用 p 的程序。指向指针的指针在 C 语言中也经常用于处理函数中的指针参数。
广告
指向包含指针的结构体的指针
还可以创建指向包含指针的结构体的指针。以下示例使用了上一节中的 Addr 记录。
typedef struct
{
char name[21];
char city[21];
char phone[21];
char *comment;
} Addr;
Addr *s;
char comm[100];
s = (Addr *)malloc(sizeof(Addr));
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);
指针 s 指向一个结构体,该结构体包含一个指向字符串的指针。
在这个例子中,如果不小心,很容易创建丢失的内存块。例如,这是 AP 示例的另一个版本。
s = (Addr *)malloc(sizeof(Addr));
gets(comm, 100);
s->comment =
(char *)malloc(sizeof(char[strlen(comm)+1]));
strcpy(s->comment, comm);
free(s);
这段代码会创建一个丢失的内存块,因为在字符串块被释放之前,包含指向字符串的指针的结构体就被释放了,如下所示。
链接
最后,可以创建能够指向相同结构体的结构体,这种能力可以用于将一系列相同的记录链接到一个称为链表的结构体中。
typedef struct
{
char name[21];
char city[21];
char state[21];
Addr *next;
} Addr;
Addr *first;
编译器允许这样做,并且只要有一点经验,就可以创建出左侧所示的结构体。