C中的动态内存分配和释放(free)
C 语言中使用函数库来解决,即在头<cstdlib>(在 C 中称为<stdlib.h>)中定义的函数:malloc ,calloc ,realloc ,free 。
(1) 函数 malloc
这个函数是给指针动态分配内存,原型:
void* malloc( size_t size );
其中nbytes 是我们想要给指针分配的内存字节数。这个函数返回一个void*类型的指针,因此我们需要用类型转换(type cast)来把它转换成目标指针所需要的数据类型,例如:
int main(int argc, const char * argv[]) {
int i;
double a;
double *pa = malloc(6 *sizeof(double));
printf("%ld\n",sizeof(pa));
for (i=0;i<6;i++) {
scanf("%lf",&a);
pa[i]=a;
printf("%lf: %p\n",pa[i],&pa[i]);
}
return 0;
}
其中
double *pa = malloc(6 *sizeof(double));
代码段将一个指向可存储6个 double 型数据的内存块的指针赋给 pa.
1 for (i=0;i<6;i++) { 2 scanf("%lf",&a); 3 pa[i]=a; 4 printf("%lf: %p\n",pa[i],&pa[i]); 5 }
该段代码是通过手动输入6个double型数据,然后再在终端输出这留个数据,并输出这六个数据所存放的内存空间的地址。
运行结果:
1 1.2 2.3 3.4 4.5 5.6 6.7
2 1.200000: 0x1006068c0
3 2.300000: 0x1006068c8
4 3.400000: 0x1006068d0
5 4.500000: 0x1006068d8
6 5.600000: 0x1006068e0
7 6.700000: 0x1006068e8
8 Program ended with exit code: 0
(2) 函数 calloc
calloc 与 malloc 在操作上非常相似,他们主要的区别是在原型上:
void* calloc (nelements, sizes);
calloc 有两个参数,第一个 nelements 表示元素个数,第二个 sizes 表示 每个元素长度,这两个参数相乘被用来计算所需内存块的总长度。例如:
1 int main(int argc, const char * argv[]) {
2 char *pb;
3 pb=(char *)calloc(3, sizeof(char));
4 strncpy(pb, "ABCD", 2);
5 printf("pb[0]=%c: %p\npb[1]=%c: %p\n",pb[0],&pb,pb[1],&pb[1]);
6 free(pb);
7 pb=(char *)calloc(2, sizeof(char));
8 printf("pb[0]=%c: %p\npb[1]=%c: %p\n",pb[0],&pb,pb[1],&pb[1]);
9 free(pb);
10
11 return 0;
12 }
代码定义了一个指针pa.
运行结果:
1 pb[0]=A: 0x7fff5fbff798 2 pb[1]=B: 0x100114441 3 pb[0]=: 0x7fff5fbff798 4 pb[1]=: 0x100114441 5 Program ended with exit code: 0
由结果可以看出,malloc 和 calloc 的另一点不同在于 calloc 会将所有的元素初始化为0。
(3) 函数 realloc
它被用来改变已经被分配给一个指针的内存的长度。函数原型如下:
void* realloc (void* pointer, nbytes);
参数 pointer 用来传递一个已经被分配内存的指针或一个空指针,而参数 nbytes 用来指明新的内存长度。这个函数给指针分配nbytes 字节的内存。这个函数可能需要改变内存块的地址以便能够分配足够的内存来满足新的长度要求。在这种情况下,指针当前所指的内存中的数据内容将会被拷贝到新 的地址中,以保证现存数据不会丢失。函数返回新的指针地址。如果新的内存尺寸不能够被满足,函数将会返回一个空指针,但原来参数中的指针pointer 及其内容保持不变。例如:
1 int main(int argc, const char * argv[]) { 2 int i; 3 char *pa =(char *)malloc(1); 4 printf("pa address=%p\n",pa); 5 strncpy(pa, "ABCDEFGH", 8); 6 for (i=0; i<10; i++) { 7 printf(" %c",pa[i]); 8 } 9 printf("\n"); 10 pa=realloc(pa,20); 11 printf("pa address=%p\n",pa); 12 strncpy(pa, "ABCDEFGH", 20); 13 for (i=0; i<10; i++) { 14 printf(" %c",pa[i]); 15 } 16 return 0; 17 }
1 pa address=0x100114440 2 A B C D E F G H 3 pa address=0x1001122e0 4 A B C D E F G H 5 Program ended with exit code: 0
(4) 函数 free
这个函数用来释放被前面 malloc , calloc 或 realloc 所分配的内存块。
void* free (void* pointer);
pointer 用来传递一个要被释放的已分配内存的指针。
在这里要特别注意:这个函数只能被用来释放由函数malloc, calloc 和realloc所分配的空间。