@skyway
2015-10-18T08:52:26.000000Z
字数 2566
阅读 978
C++
title: 内存分配malloc、realloc
date: 2015-09-01 17:30:28
catagories: 编程
tags: [C++, realloc, calloc, alloca, memmove]
先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回;如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域,同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。
void *realloc(void *ptr, size_t size)
#include <stdio.h> /* printf, scanf, puts */
#include <stdlib.h> /* realloc, free, exit, NULL */
int main()
{
char *str;
/* 最初的内存分配 */
str = (char *) malloc(15);
strcpy(str, "jikexueyuan");
printf("String = %s, Address = %un", str, str);
/* 重新分配内存 */
str = (char *) realloc(str, 25);
strcat(str, ".com");
printf("String = %s, Address = %un", str, str);
free(str);
return(0);
}
void *ptr = realloc(ptr, new_size);
if (!ptr) {
// 错误处理
}
正确处理:
void *new_ptr = realloc(ptr, new_size);
if (!new_ptr) {
// 错误处理。
}
ptr = new_ptr
void *new_ptr = realloc(old_ptr, new_size);
//其它代码
free(new_ptr);
calloc函数得到的内存空间是经过初始化的,其内容全为0。calloc函数适合为数组申请空间,可以将size设置为数组元素的空间长度,将n设置为数组的容量。
void *calloc(size_t nobj, size_t size);
分配足够的内存给nobj个大小为size的对象组成的数组,并返回指向所分配区域的第一个字节的指针;若内存不够,则返回NULL,该空间的初始化大小为0字节。
char *p = (char *) calloc(100,sizeof(char));
calloc函数的分配的内存也需要自行释放
void* malloc(size_t size);
分配足够的内存给大小为size的对象,并返回指向所分配区域的第一个字节的指针;若内存不够,则返回NULL. 不对分配的空间进行初始化.
char *p = (char *)malloc(sizeof(char));
通过malloc函数得到的堆内存必须使用memset函数来初始化:
void * memset (void * p,int c,int n) ;
使用free()函数来释放内存空间,但是,free函数只是释放指针指向的内容,而该指针仍然指向原来指向的地方,此时,指针为野指针,如果此时操作该指针会导致不可预期的错误。安全做法是:在使用free函数释放指针指向的空间之后,将指针的值置为NULL。
其调用序列与malloc相同,但是它是在当前函数的栈帧上分配存储空间,而不是在堆中。其优点是:当函数返回时,自动释放它所使用的栈帧,所以不必释放空间。其缺点是:某些系统在函数已被调用后不能增加栈帧长度,于是也就不能支持alloca 函数。
使用malloc,calloc,realloc函数分配的内存空间都要使用Free函数或者指针参数为NULL的realloc函数来释放。
对于用户自定义的对象而言,用maloc/free无法满足动态管理对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。
void *memcpy(void *dst, const void *src, size_t count);
void *memmove(void *dst, const void *src, size_t count);
唯一的区别是,当内存发生局部重叠的时候,memmove保证拷贝的结果是正确的,memcpy不保证拷贝的结果的正确。但memcopy比memmove的速度要快一些。
第一种:拷贝重叠的区域不会出现问题,内容均可以正确的被拷贝。
第二种:问题出现在右边的两个字节,这两个字节的原来的内容首先就被覆盖了,而且没有保存。所以接下来拷贝的时候,拷贝的是已经被覆盖的内容,显然这是有问题的。