1. malloc/calloc/realloc和free
#include <iostream>
using namespace std;
void Test () {
int* p1 = (int*) malloc(sizeof(int));
free(p1);
// 1.malloc/calloc/realloc的区别是什么?
int* p2 = (int*)calloc(2, sizeof (int)); // 申请元素个数 大小
int* p3 = (int*)realloc(p2, sizeof(int)*10);
// 这里需要free(p2)吗?
free(p3 );
}
malloc:一般在C语言中采用malloc进行申请空间,算是很熟悉、很常用了。
calloc:申请内存并且初始化,其按位进行初始化,将每一位初始化为全0。
realloc:其主要作用为改变容量。
由malloc申请的p1所指向空间内容为随机值。
由calloc申请的空间按位将p2所申请的16位空间置为0。
由realloc所改变的空间大小,但其不具备初始化空间的内容。在此,p3改变p2的大小,不改变其内容,即仍然为0。
realloc在改变空间大小时有两种方案:
空间起始具有头指针,在所申请空间末尾有标记,用以与头指针共同记录空间大小。现在申请一片更大的空间时:
1)若尾指针后即跟了一片相应大小的空间,那么就将标记移换到后空间末尾处进行标记,此时头指针未发生改变,即该地址空间改变前后未发生改变。
2)若在申请大空间时,尾指针后续无适宜的连续空间,那么就会释放原有空间,并重新申请一片满足要求的连续空间,此时头指针发生了改变,那么改变前后空间位置即发生了变化。
int main() {
int* p1 = (int*)malloc(sizeof(int));
free(p1);
// 1.malloc/calloc/realloc的区别是什么?
int* p2 = (int*)calloc(4, sizeof(int));
int* p3 = (int*)realloc(p2, 10000); // 申请10000字节大空间
// 这里需要free(p2)吗?
free(p3);
system("pause");
return 0;
}
此时,改变p2的空间大小为10000字节,我们会发现p2与p3起始位置发生变化。realloc不仅能够扩容也可以缩容。可以通过其返回值是否为0来进行realloc成功与否的标志。
在缩小时可能会遇到这样一种情况,初始p2calloc申请的地址初始化为全零,需要对p2空间大小做缩小操作,故被释放,内容为随机值,接着realloc作用p3下就接着p2首地址进行申请出p3,导致p2、p3地址相同而内容均变为相同随机值。这只是重新找了一个地址只不过这个地址和原来相同,这只是个美丽的巧合...在我的电脑上没有调出来这个现象,就此当做理论知识吧。
p2、p3只需要释放一个,如果说p2在原有空间上进行拼接,那么返回的地址仍为p2的地址,那么只需要释放p3,如果说,在此重新分配了空间,那么realloc函数内部已经将p2空间释放了,若自己进行手动释放相当于释放了两次空间,造成error。