C-内存函数,动态内存
一、内存函数
==================================================================
1、void* memcpy(void* dest,const void* src,size_t num);内存copy函数。将src中的内容,copy num个字节到dest中;copy两块独立空间的数据。
void* memcpy(void* dest,const void* src,size_t num);
int src[] = {1,2,3,4,5,6};
int dest[10] = {0};
memcpy(dest,src,6*4);//将src中的数据复制到dest中
2、void* memmove(void* dest,const void* src,size_t num),copy两块有关联空间的数据
void* memmove(void* dest,const void* src,size_t num)
int dest[] = {1,2,3,4,5,6};
memcpy(dest+3,dest,3*4);//将dest中的123,复制到456,输出123123
3、int memcmp(const void* dest,const void* src,size_t num);内存比较num个字节的数据是否相等。
int memcmp(const void* dest,const void* src,size_t num);
返回值:dest< src,return <0;dest== src,return =0;dest> src,return >0;
4、void* memset(void* dest,int num,size_t size);内存设置,按字节为单位进行初始化
void* memset(void* dest,int num,size_t size);
/*
dest:需要设置内存的空间的起始地址
num:需要设置的元素,会先将参数转换成ascII码后再复制,可以传char类型
size:需设置的字节数
*/
二、动态内存
内存泄漏:申请了一篇空间,但是没有释放,导致这篇内存空间无法被其他对象试用也无法释放,浪费的这篇内存就是内存泄露。
1、动态内存函数
①、malloc:开辟指定字节个数的内存,并返回内存地址;申请失败返回NULL,maloc传参如果是传入0,可以忽略,表示未定义;
void* malloc(size_t size);
开辟40字节的空间,用来保存int类型的数据
#include <stdlib.h>
#include<string.h>
int main()
{int* p = (int*)malloc(40);if (p == NULL) {printf("%s\n", strerror(errno));return 1;}int i = 0;for (i = 0; i < 10; i++) {*(p + i) = i;}for (i = 0; i < 10; i++) {printf("%d ", *(p + i));}return 0;
}
②、free
malloc 申请,free释放,成对出现,避免内存泄漏,free只能释放动态参加的内存。
free(NULL):此时什么都不操作。
//申请开辟空间int* p = (int*)malloc(40);//释放内存free(p);//free(p)虽然将申请的内存空间释放掉了,但是此时p是一个野指针,//依旧可以通过p找到这篇空间的地址,为了保证内存安全,将p置为NULL即可。p = NULL;
③、calloc
num:开辟元素的个数
size:每个元素的大小
calloc函数在开辟空间后,会将开辟的空间全都初始化为0后再返回。使用结束后,通过free函数释放空间。
void* calloc (size_t num,size_t size);
④、realloc
动态调整内存空间的大小
void* realloc(void* ptr,size_t size);
ptr:要修改空间的起始地址
size:将ptr指向的空间重置为size大小的新空间
realloc工作原理:
情况1:realloc(p,40);p指针后面连续的空间p+40个字节的空间是空闲的,那么就直接扩展40个字节后,返回p;即在连续空间上扩展
情况2:realloc(p,40);p指针后面没有连续的空闲空间,那么会在内存中查找空闲的40个字节大小的空间后,将原来内存空间的数据memcpy到新空间后,free原空间内存,返回新空间地址
情况3:realloc(p,INT_MAX);扩展的空间太大,那么会返回NULL;因此realloc会出现扩容失败的场景,所以在接受realloc返回值时,不应该使用原空间地址直接接收,应该先判断扩展后返回的指针是否为NULL,避免返回指针为NULL接收导致原数据丢失。
2、常见的动态内存错误
①、对NULL指针的解引用操作
②、对动态开辟的内存空间越界访问
③、对非动态开辟空间的内存进行free
④、使用free释放动态开辟内存的一部分
⑤、对同一块空间多次释放
⑥、动态内存开辟忘记释放(内存泄漏)