malloc,calloc,realloc,memset之间的关系
2017-09-14 11:38
344 查看
阅读下面文章可以同时参考C运行时库(C run-time library)
1.首先要了解的是:
堆栈区(stack):由编译器自动分配与释放,存放函数的参数值,局部变量,临时变量等等,它们获取的方式都是由编译器自动执行的
堆区(heap):一般由程序员分配与释放,基程序员不释放,程序结束时可能由操作系统回收(C/C++没有此等回收机制,Java/C#有),注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
全局区(静态区)(static):全局变量和静态变量的存储是放在一块儿的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。
文字常量区:常量字符串是放在这里的,程序结束后由系统释放。
程序代码区:存放函数体的二进制代码。
2.malloc()可以从堆上获得指定字节的内存空间
void *malloc(
size_t size
);
(1)形参size为要求分配的字节数。
(2)如果函数执行成功,malloc返回获得内存空间的首地址;如果函数执行失败,那么返回值为NULL。
(3)由于 malloc函数值的类型为void型指针,因此,可以将其值类型转换后赋给任意类型指针,这样就可以通过操作该类型指针来操作从堆上获得的内存空间。
(4)malloc函数分配得到的内存空间是未初始化的。因此,一般在使用该内存空间时,要调用另一个函数memset来将其初始化为全0。
3.memset()将指定的内存空间按字节单位置为指定的字符
void *memset(
void *dest,
int c,
size_t count
);
该函数可以将指定的内存空间按字节单位置为指定的字符c。其中,dest为要清零的内存空间的首地址,c为要设定的值,count为被操作的内存空间的字节长度。如果要用memset清0,变量c实参要为0。
4.calloc函数的功能与malloc函数的功能相似,都是从堆分配内存
void *calloc(
size_t num,
size_t size
);
(1)calloc函数为数组分配存储空间num元素,每个长度size字节。 每个元素初始化为 0。
(2)calloc返回指向分配的空间的指针。 返回值指向的存储空间保证适当对齐任何类型的对象的存储。 若要获取指向一种类型的指针,而不是返回void,应使用类型转换。
5.realloc()可以实现内存分配和内存释放的功能
void *realloc(
void *memblock,
size_t size
);
(1)指针memblock必须为指向堆内存空间的指针,即由malloc函数、calloc函数或realloc函数分配空间的指针。
(2)realloc函数将指针 memblock指向的内存块的大小改变为size字节。如果size小于或等于memblock之前指向的空间大小,那么。保持原有状态不变。如果size大于原来memblock之前指向的空间大小,那么,系统将重新为memblock从堆上分配一块大小为size的内存空间,同时,将原来指向空间的内容依次复制到新的内存空间上,memblock之前指向的空间被释放。relloc函数分配的空间也是未初始化的。
???(3)realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平;可如果数据后面的字节不够的话,问题就出来了,那么就使用堆上第一个有足够大小的自由块,现存的数据然后就被拷贝至新的位置,而老块则放回到堆上。
6.free()
void free(
void *memblock
);
(1)从堆上获得的内存空间在程序结束以后,系统不会将其自动释放,需要程序员来自己管理。一个程序结束时,必须保证所有从堆上获得的内存空间已被安全释放,否则,会导致内存泄露
(2)若释放了无效的指针(malloc/calloc/realloc的指针指向未分配的内存块),可能会影响后续分配请求,并导致错误
注意:
1.有经验的程序员更喜欢使用calloc(),因为这样的话新分配内存的内容就不会有什么问题,调用calloc()肯定会清0,并且可以避免调用memset().
2.进程对动态内存的请求被认为是不紧迫的。例如,当进程的可执行文件被装入时,进程并不一定立即对所有的代码进行访问。类似地,当进程调用malloc() 请求动态内存时,并不意味着进程很快就会访问所有获得的内存。因此一般来说,内核总是尽量推迟给用户态进程动态分配内存。
3.malloc()函数有一个参数,即分配的内存空间的大小,malloc在分配内存的时候会保留一定的空间用来记录分配情况,分配的次数越多,这些记录占用的空间就越多。另外,根据malloc实现策略的不同,malloc每次在分配的时候,可能分配的空间比实际要求的多些,多次分配会导致更多的这种浪费,当然,这些都跟malloc的实现有关;
4.relloc()可以对给定的指针所指的空间进行扩大或者缩小,无论是扩张或者缩小,原有内存中的内容将保持不变。当然,对于缩小,则被缩小的那一部分的内容会丢失。
relloc()并不保证调整后的内存空间和原来的内存空间保持同一内存地址,相反,relloc返回的指针很可能指向一个新地址。所以在代码中,我们必须将relloc的返回值,重新赋值给memblock : memblock =(size_t *) relloc (memblock ,sizeof(size_t )*15);
1.首先要了解的是:
堆栈区(stack):由编译器自动分配与释放,存放函数的参数值,局部变量,临时变量等等,它们获取的方式都是由编译器自动执行的
堆区(heap):一般由程序员分配与释放,基程序员不释放,程序结束时可能由操作系统回收(C/C++没有此等回收机制,Java/C#有),注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
全局区(静态区)(static):全局变量和静态变量的存储是放在一块儿的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。
文字常量区:常量字符串是放在这里的,程序结束后由系统释放。
程序代码区:存放函数体的二进制代码。
2.malloc()可以从堆上获得指定字节的内存空间
void *malloc(
size_t size
);
(1)形参size为要求分配的字节数。
(2)如果函数执行成功,malloc返回获得内存空间的首地址;如果函数执行失败,那么返回值为NULL。
(3)由于 malloc函数值的类型为void型指针,因此,可以将其值类型转换后赋给任意类型指针,这样就可以通过操作该类型指针来操作从堆上获得的内存空间。
(4)malloc函数分配得到的内存空间是未初始化的。因此,一般在使用该内存空间时,要调用另一个函数memset来将其初始化为全0。
3.memset()将指定的内存空间按字节单位置为指定的字符
void *memset(
void *dest,
int c,
size_t count
);
该函数可以将指定的内存空间按字节单位置为指定的字符c。其中,dest为要清零的内存空间的首地址,c为要设定的值,count为被操作的内存空间的字节长度。如果要用memset清0,变量c实参要为0。
4.calloc函数的功能与malloc函数的功能相似,都是从堆分配内存
void *calloc(
size_t num,
size_t size
);
(1)calloc函数为数组分配存储空间num元素,每个长度size字节。 每个元素初始化为 0。
(2)calloc返回指向分配的空间的指针。 返回值指向的存储空间保证适当对齐任何类型的对象的存储。 若要获取指向一种类型的指针,而不是返回void,应使用类型转换。
5.realloc()可以实现内存分配和内存释放的功能
void *realloc(
void *memblock,
size_t size
);
(1)指针memblock必须为指向堆内存空间的指针,即由malloc函数、calloc函数或realloc函数分配空间的指针。
(2)realloc函数将指针 memblock指向的内存块的大小改变为size字节。如果size小于或等于memblock之前指向的空间大小,那么。保持原有状态不变。如果size大于原来memblock之前指向的空间大小,那么,系统将重新为memblock从堆上分配一块大小为size的内存空间,同时,将原来指向空间的内容依次复制到新的内存空间上,memblock之前指向的空间被释放。relloc函数分配的空间也是未初始化的。
???(3)realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平;可如果数据后面的字节不够的话,问题就出来了,那么就使用堆上第一个有足够大小的自由块,现存的数据然后就被拷贝至新的位置,而老块则放回到堆上。
6.free()
void free(
void *memblock
);
(1)从堆上获得的内存空间在程序结束以后,系统不会将其自动释放,需要程序员来自己管理。一个程序结束时,必须保证所有从堆上获得的内存空间已被安全释放,否则,会导致内存泄露
(2)若释放了无效的指针(malloc/calloc/realloc的指针指向未分配的内存块),可能会影响后续分配请求,并导致错误
注意:
1.有经验的程序员更喜欢使用calloc(),因为这样的话新分配内存的内容就不会有什么问题,调用calloc()肯定会清0,并且可以避免调用memset().
2.进程对动态内存的请求被认为是不紧迫的。例如,当进程的可执行文件被装入时,进程并不一定立即对所有的代码进行访问。类似地,当进程调用malloc() 请求动态内存时,并不意味着进程很快就会访问所有获得的内存。因此一般来说,内核总是尽量推迟给用户态进程动态分配内存。
3.malloc()函数有一个参数,即分配的内存空间的大小,malloc在分配内存的时候会保留一定的空间用来记录分配情况,分配的次数越多,这些记录占用的空间就越多。另外,根据malloc实现策略的不同,malloc每次在分配的时候,可能分配的空间比实际要求的多些,多次分配会导致更多的这种浪费,当然,这些都跟malloc的实现有关;
4.relloc()可以对给定的指针所指的空间进行扩大或者缩小,无论是扩张或者缩小,原有内存中的内容将保持不变。当然,对于缩小,则被缩小的那一部分的内容会丢失。
relloc()并不保证调整后的内存空间和原来的内存空间保持同一内存地址,相反,relloc返回的指针很可能指向一个新地址。所以在代码中,我们必须将relloc的返回值,重新赋值给memblock : memblock =(size_t *) relloc (memblock ,sizeof(size_t )*15);
相关文章推荐
- C语言中 malloc,calloc 和 realloc 函数之间的区别
- malloc、realloc、calloc之间区别
- malloc、calloc、realloc之间的区别
- malloc(),calloc()和realloc()函数的区别
- C语言realloc,malloc,calloc的区别
- 3 定义两个整型指针,分别用malloc、calloc对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行赋值随机范围1-3,赋值后用memcmp比较两个数组。如果相同
- malloc ? realloc ? free ? calloc ?
- realloc,malloc,calloc的区别及free(zz)
- 内存分配函数 :malloc,calloc,realloc
- calloc,malloc和realloc
- realloc,malloc,calloc的区别
- C语言三个内存分配函数比较,malloc calloc realloc
- malloc realloc calloc 的区别和联系 .
- malloc与calloc,realloc动态内存的用法
- _alloca/malloc/calloc/realloc/sbrk/new/delete
- malloc、calloc、realloc的区别
- realloc,malloc,calloc三者的区别
- alloca malloc realloc calloc
- malloc()、free()、calloc()与realloc()
- malloc、realloc、calloc区别