这
里原始内存中的数据还是保持不变的。
当内存不再使用时,
应使用
free()
函数将内存块释放
一、动态内存分配
数组的元素存储于内存的连续位置,数组可以在声明后编译就分配所需内存,也可以使用动态内存分配在运行时为他分配内存。
1.1当声明数组时,必须用一个编译时常量为数组指定数组长度,这种分配内存的方的优缺点如下:
1.1.1优点:
1. 使用简单只需在编译时常量指定数组长度。
1.1.2缺点:
1.如果不确定数组内运行时具体需要多少内存,一旦实际元素超过分配的内存则出错。
2.如果为了解决第一个缺点而大量声明内存空间,一旦实际元素过少时会严重浪费内存空间
1.2执行内存分配和释放函数
这些函数都在C函数库stdlib.h中
1.2.1 malloc
1.函数原型:void *malloc(size_t size);
size_t是一个无符号类型定义于stdlib.h中 size即为分配的内存大小返回值是指向内存起始位置的指针,由于使用返回指针的类型为void * 型指针所以标准的表示void *类型指针可以转换成任意类型指针,但是有些编译器可能要求使用强制类型转换。
char* p;
p=(char*)malloc(20);
内存并未初始化,如果需要的话则需要手动初始化或者使用calloc函数。实际分配内存时可能回避你要求的超微多一旦,这个由编译器决定所以不能指望他肯定会分配连续的要求内存。如果申请内存为空的或者申请的内存系统无法满足要求,则会返回一个NULL指针,所以每个申请的内存必须检查返回指针,确保它并非NULL。NULL 实际上是字面值常量0。他在这里骑着视觉提醒作用告诉我们我们测试的是一个指针而不是整数。
1.2.2 calloc
1.函数原型: void *calloc( size_t num_elements, size_t exement_size);
calloc不同于malloc是calloc会在返回指针之前把申请内存初始化为0,如果0不是想初始化的内容则这里会浪费时间。num_element是要初始化的元素数量而 element_size时要初始化元素每个占用字节数,通过这些可以计算总共需要的分配的内存。
1.2.3 realloc
1.函数原型:void *realloc( void *ptr , size_t new_size);
realloc用于修改一个原来已经分配的内存块的大小。可以扩大一个内存块则原来的内容保留新增加的内存添加到原先内存块后面,可以缩小内存则缩小尾部的部分内存,剩余的内存和数据保留。如果原先的内存无法改变大小,则realloc会重新分配一个正确的大小的内存,并把原先的内容复制到新的快上,新词在使用realloc后你就不能在使用原来的指向内存的指针了,而是应该使用realloc所返回的新指针。
2 特殊情况:
(1)如果ptr = NULL 那么相当于调用malloc (size) size=0那么相当于调用了free(prt)。
(2)如果修改的内存小于实际的内存则会直接返回原来的内存地址。
(3)如果修改的内存大于实际的内存
1.realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,则可以成功则返回原来内存指针地址。
2.若堆的内存不足时则直接在堆里找一块新的内存为new_size的空间同时把原先的内容拷贝到新地址函数返回新内存地址,
这
里原始内存中的数据还是保持不变的。
当内存不再使用时,
应使用
free()
函数将内存块释放
这里原始内存中的数据还是保持不变的。当内存不再使用时,应使用free()函数将内存块释放。这
里原始内存中的数据还是保持不变的。
当内存不再使用时,
应使用
free()
函数将内存块释放
3.这
里原始内存中的数据还是保持不变的。
当内存不再使用时,
应使用
free()
函数将内存块释放
如果申请失败,将返回NULL,此时,原来的指针仍然有效下面就举两个例子,来说明一下。
1) realloc() 第一种行为引发的Bug
- void *ptr = realloc(ptr, new_size);
- if (!ptr) {
- // 错误处理
- }
正确的处理应该是这样:
- void *new_ptr = realloc(ptr, new_size);
- if (!new_ptr) {
- // 错误处理。
- }
- ptr = new_ptr
2) 第三种行为引发的Bug
实际上,malloc(0)是合法的语句,会返还一个合法的指针,且该指针可以通过free去释放。这就造成了很多人对realloc()的错误理解,认为当size为0时,实际上realloc()也会返回一个合法的指针,后面依然需要使用free去释放该内存。
- void *new_ptr = realloc(old_ptr, new_size);
- //其它代码
- free(new_ptr);
所以,realloc() 这个设计并不怎么优良的函数陷阱还是不少的,一不小心就踩雷了,上面只是两个简单的小例子,大家在实际使用的时候还应该注意一些其他小问题。
1.2.4 free
1.函数原型:void free(void *pointer);
这
里原始内存中的数据还是保持不变的。
当内存不再使用时,
应使用
free()
函数将内存块释放
功 能: 与malloc()函数配对使用,释放malloc函数申请的动态内存。(另:对于free(p)这句语句,如果p 是NULL 指针,那么free 对p 无论操作多少次都不会出问题。如果p 不是NULL 指针,那么free 对p连续操作两次就会导致程序运行错误。这
里原始内存中的数据还是保持不变的。
当内存不再使用时,
应使用
free()
函数将内存块释放