C语言之动态内存开辟

C语言中内存开辟

必须要引入头文件 <stdlib.h> 三种开辟方式 ### 1. malloc 先来看看函数原型:void* malloc (size_t size);

可以从文档里看出,该函数参数是一个要开辟的字节数。

具体怎么操作呢:

   //因为返回的是一个指向块开头的指针,因此我们需要强转成指针类型
   int* p1 = (int*) malloc(sizeof(int));  
   free (p1);  //malloc开辟的空间需要 free 来释放空间,否则会造成内存泄漏

### 2. reallocvoid* realloc ( void * ptr, size_t size ); 它说的是什么意思呢? 简单地说就是,该函数可以将内存块移动到新的位置,在这种情况下,将返回新的位置。即使块被移动,内存块的内容也会保留到新旧大小中较小的大小。如果新大小较大,则新分配的部分的值不确定。在ptr为空的情况下,该函数的行为与malloc完全相同,它分配一个新的大小字节块,并返回一个NULL。

ptr:指向先前用malloc、calloc或realloc分配的内存块的指针,以便重新分配。 size: 指内存块的新大小(以字节为单位)。如果它是0, ptr指向一个现有的内存块,那么ptr指向的内存块将被回收,并返回一个空指针。

### 3. callocvoid* calloc ( size_t num, size_t size ); 该函数的功能是: 为num元素数组分配一个内存块,每个元素的大小都是字节长,并将其所有的 初始化为0。

三种内存开辟具体实例

void Test()
{
	int* p1 = (int*)malloc(sizeof(int));
	free(p1);
	
	int* p2 = (int*)calloc(4, sizeof(int));
	int* p3 = (int*)realloc(p2, sizeof(int) * 10);
	
	// 这里需要free(p2)吗?
	free(p3);        //答案当然是不需要的啊,原因我已经在上面说过,还不理解的在翻到上面去看看
}

三种内存开辟方式比较和总结

  1. malloc 、realloc、calloc三个函数都是用来动态开辟内存的,并且开辟的都是一段连续的内存。
  2. malloc和realloc:realloc主要是用于修改一个原先已经分配好的内存块的大小;而malloc主要是用来开辟一个以字节为单位的新的内存块。
  3. 如果realloc是用来扩大或者缩小一个内存块: ●扩大内存块:那么这块内存原来的内容依然保留,新增的内存添加到原内存快的后面,新增加的空间并没有进行初始化,只是增加了大小; ●缩小内存:该内存块尾部部分的内存会被拿掉,剩余部分依旧保留; ●如果该内存块无法改变大小, realloc 就会重新分配一块正确的内存,并把原来内存的内容复制到新的内存块上。因此,在使用realloc之后,就不能再使用指向旧空间的指针,而是使用realloc返回的新指针
  4. calloc和malloc 主要是前者在返回指向内存的指针之前把它初始化为 0。并且calloc参数包括所需元素的数量和每个元素的字节数。根据这些值来计算总共需要分配多少内存。
  5. 使用完之后必须要用 free 释放空间,否则会造成内存泄漏。

内存泄漏(非常重要)

当动态分配的内存不再需要使用时,这块内存就应该被释放,这样可以被重新分配使用。分配但不在使用完成之后释放内存会造成内存泄漏。 内存泄漏最终将会一点一点的榨干内存,最后只能重启。万一实在一个大型的服务器,那后果难以想象,对于一个程序猿来说大概就差不多可以收拾东西滚蛋了,啊哈哈哈哈。

常见的动态内存错误

  1. 对NULL的解引用
  2. 对分配的内存进行操作时越过边界
  3. 释放非动态分配的内存
  4. 试图释放一块动态分配的内存的一部分以及一块动态内存被释放之后继续使用。
  5. malloc 和 free没有配套使用
  6. 对动态开辟的内存重复释放 </stdlib.h>