realloc引起的coredump
记录一次接口程序在运行过程中产生的崩溃问题,通过调试
core文件,定位到是程序在调用realloc 时候出现了问题
问题程序代码
#include
#include
#include
#include
//linux memalign 头文件
char * pData = NULL;
int create_canvas (int width, int
height)
{
if (pData == NULL) {
pData = (char *) memalign (32, width *
height);
printf("memalign success pData %p \n",
pData);
} else {
char *ptr = (char *)realloc(pData, width *
height);
if (ptr == NULL) {
printf("relloc failed and pData %p
\n",pData);
//pData = NULL; //加上这句就不会崩溃了
} else {
pData = ptr;
printf("relloc success pData %p \n",
pData);
}
}
}
int main()
{
int count = 0;
while (++count < 5) {
printf("count %d and ",count);
if (1 == count)
create_canvas(1024,768);
else if (2 == count)
create_canvas(0,0);
else
create_canvas(1024,768);
sleep(1);
//Sleep(1000); windows 下用这个
}
return 0;
}
执行结果
原因:count == 2 时,即width * height =
0,导致realloc释放空间,pData 会被free 掉,但它的地址仍然是0x7fe9961cd040
并没有被赋值为NULL,所以成了前面说的野指针(指向垃圾内存);这样当count == 3时,就会导致realloc
发生段错误(SIGNAL 11)而产生崩溃。
代码不妥处
如果第二次调用传递的width * height(即传给realloc的)
小于第一次传递的width *
height(即传给memalign的)就可能会发生数据丢失的情况,这个不是本文说明的重点,点到为止。
realloc原型
void *realloc(void *mem_address, unsigned
int newsize);
指针名=(数据类型*)realloc(要改变内存大小的指针名,新的大小)
1、realloc失败的时候,返回NULL
2、realloc失败的时候,原来的内存不改变,不会释放也不会移动
3、假如原来的内存后面还有足够多剩余内存的话,realloc的内存=原来的内存+剩余内存,realloc还是返回原来内存的地址;
假如原来的内存后面没有足够多剩余内存的话,realloc将申请新的内存(地址漂移),然后把原来的内存数据拷贝到新内存里,原来的内存将被free掉,
realloc返回新内存的地址。
4、如果size为0,效果等同于free()。
5、传递给realloc的指针必须是先前通过malloc(), calloc(),
或realloc()分配的,或者是NULL
6、传递给realloc的指针可以为空,等同于malloc。
常见缺陷用法
用法一:p = (int *) realloc (p, sizeof(int)
*15);语句有这么一个问题,调用前p指向一个已分配成功的内存,而调用realloc时却失败(即返回NULL),此时,p原来指向的内存还没有free掉,而现在又找不到地址,这样就出现memory
leak。
用法二:char *p,*q;
p = (char * ) malloc (10);
q=p;//地址游离,q变为野指针
p = (char * ) realloc (p,20);
最好解决方案
//访问内存一直使用p
char*q;
q = (char *) realloc (p, 15);
if(!q) p =q;
…
最后free(p),将p、q指向null