c primer plus P340
为了在程序运行时分配内存。 在头文件stdlib.c中有malloc()和free()的原型。
malloc()接受一个参数:所需内存字节数,然后malloc()找到可用内存中一个大小适合的块,返回那块内存第一个字节的地址。
ANSI C标准使用了一个新类型:指向void的指针,被用作“通用指针”。
例:
double *ptd;
ptd = (double *)malloc(30 * sizeof(double)); //以前没理解malloc和void的意思的时候,感觉这句话怎么这么麻烦,但是理解了之后才发现,这句话真的是词词不可少啊。
因为数组的名字是它第一个元素的地址,反过来用,可以用ptd当作数组名,使用ptd[0]访问内存块的第一个元素,ptd[1]访问第二个元素。
如前,C99引入了动态数组。
然而,即使在C99之前的编译器中,也可以这样做:
ptd = (double *)malloc(n * sizeof(double));
对应每个malloc()调用,应该调用一次free(). 函数free()的参数是先前malloc()返回的地址,它释放先前分配的内存。
exit()的原型也在stdlib.c中。 exit()用来在内存分配失败时结束程序。值EXIT_FAILURE 也在这个头文件中定义。标准库提供了两个保证能够在所有操作系统下工作的返回值:EXIT_SUCCESS (或者,等同于0)指示程序正常终止,EXIT_FAILURE指示程序异常终止。
例12.14:
while(i < max && scanf("%lf", &ptd[i]) == 1) //这里允许输入至多max个数据,i记录输入了多少
++i;
printf("Here are your %d entries: /n", number = i ); //这里输出i值的同时,将number赋值
for(i = 0; i < number; i++) //i回成0,number作为那个"哨兵",将输入的输出依次读出来
。。。
另外注意:putchar()里面的参数需要是个字符,不能是字符串,所以要用单引号不要用双引号。要是想换行的话:putchar('/n');
接上面的for语句:
{
printf("%7.2f", ptd[i]);
if(i % 7 == 6) //满六个数换行
{
putchar('/n');
}
}
if(i % 7 != 0) //最后一行,不满六个,换行
{
putchar('/n');
}
puts("Done");
注意free()函数,在这个特定的例子中,使用free()不是必须的,因为在程序终止后所有已分配的内存都将被自动释放。然而在一个更复杂的程序中,能够释放并在利用内存将是重要的。
内存泄漏 memory leak
函数calloc():
long * newmem;
newmem = (long*)calloc(100, sizeof(long));
calloc()函数有两个参数,第一个是所需内存单元的数量,第二个是每个单元以字节计的大小。
函数calloc()还有一个特性,它将块中的全部位都置为0.
函数free()也可以用来释放由calloc()分配的内存。
动态内存分配和变长数组:
变长数组VLA,是自动存储的,在运行完定义部分之后会自动释放。
二维数组:
int n = 5;
int m= 6;
int ar2[n][m];
int (*p2)[6]; //p2指向一个包含6个int值的数组。p2[i]将被解释为一个由6个整数构成的元素,p2[i][j]将是一个int值。
int (*p3)[m];
p2 = (int (*)[6]) malloc(n * 6 * sizeof(int)); //n*6数组
p3 = (int (*)[m]) malloc(n * m *sizeof(int)); //n*m数组