prev up next   top/contents search

comp.lang.c FAQ 列表· 问题 7.30

将空指针作为第一个参数传递给realloc是否合法?为什么会有人这样做?


ANSI C 允许这种用法(以及相关的realloc(..., 0),它会释放内存),尽管一些早期实现不支持它,所以它可能不是完全可移植的。向realloc传递一个初始为空指针可以使编写一个自启动的增量分配算法更容易。

下面是一个例子——该函数将任意长度的行读入动态分配的内存,并在必要时重新分配输入缓冲区。(调用者必须在不再需要返回的指针时free它。)

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

/* read a line from fp into malloc'ed memory */
/* returns NULL on EOF or error */
/* (use feof or ferror to distinguish) */

char *agetline(FILE *fp)
{
	char *retbuf = NULL;
	size_t nchmax = 0;
	register int c;
	size_t nchread = 0;
	char *newbuf;

	while((c = getc(fp)) != EOF) {
		if(nchread >= nchmax) {
			nchmax += 20;
			if(nchread >= nchmax) {	/* in case nchmax overflowed */
				free(retbuf);
				return NULL;
			}
#ifdef SAFEREALLOC
			newbuf = realloc(retbuf, nchmax + 1);
#else
			if(retbuf == NULL)	/* in case pre-ANSI realloc */
				newbuf = malloc(nchmax + 1);
			else	newbuf = realloc(retbuf, nchmax + 1);
#endif
						/* +1 for \0 */
			if(newbuf == NULL) {
				free(retbuf);
				return NULL;
			}

			retbuf = newbuf;
		}

		if(c == '\n')
			break;

		retbuf[nchread++] = c;
	}

	if(retbuf != NULL) {
		retbuf[nchread] = '\0';

		newbuf = realloc(retbuf, nchread + 1);
		if(newbuf != NULL)
			retbuf = newbuf;
	}

	return retbuf;
}
(在生产代码中,像nchmax += 20这样的行可能会有问题,因为该函数可能会进行大量重新分配。许多程序员更喜欢乘法重新分配,例如nchmax *= 2,尽管它显然不是那么自启动,并且在需要分配一个巨大的数组但内存有限时会遇到问题。)

参考文献:ISO Sec. 7.10.3.4
H&S Sec. 16.3 p. 388


prev up next   contents search
关于此 FAQ 列表   关于 Eskimo   搜索   反馈   版权

Eskimo North 托管