error realloc(): invalid next size 崩溃

##前言:
记录一次使用ealloc()崩溃的问题,
##代码现状:
我的代码如下:

void CSimpleBuffer::Extend(uint32_t len)
{
    m_alloc_size = m_write_offset + len;
    m_alloc_size += (m_alloc_size >> 2);	// increase by 1/4 allocate size
    void* new_buf = realloc((void*)m_buffer, m_alloc_size);
    m_buffer = (uchar_t*)new_buf;
}

m_alloc_size:buf的总大小
m_write_offset:buf已经被使用的大小
len:要拓展的大小

##问题描述
上面的代码,第一次调用时正常,第二次调用时必崩溃

##原因分析
上网查资料说invalid next size的错误是指新申请的空间小于旧的空间,自己写了个demo验证了一下,发现并非这样,demo代码如下:

int main5(int argc, char **argv)
{
    void* ptr = NULL;
    void* newPtr = realloc(ptr, 1025);

    ptr = newPtr;

    memset(ptr, 'A', 1025);

    int t = 0;
    printf("~~~~~~~~~~~~~~~~~~\n");

    void* str = realloc(ptr, 800);
    ptr = str;

    printf("222222222222,   ptr = %p,\n %s\n", ptr, ptr);
}

运行正常,未出现崩溃。
##根本原因
我的代码中,realloc之前,我向该buf(realloc第一个参数)中插入了一些数据,插入数据的长度处理错误:该buf是二进制数据,却被我当string类型处理
然后在realloc()时,越界访问该buf,堆空间使用错误,导致崩溃。大家可以参考:http://bbs.csdn.net/topics/340193758,第17楼所说,摘要如下:

比如你分配内存后,得到的地址是0x80300000, 长度是0x200那么地址0x802FFFF0位置放的就是控制信息,表明下一个内存block被使用了,同时该信息指明接下来可用的一个block地址在0x80300200开始。当这些控制信息被你因为越界给写坏了,内存的分配和释放就会出错,因为这些操作要根据这些信息找到你要释放的区域,做好标记为已释放。
##总结
崩溃问题多是内存使用不当导致,如果不能从崩溃现象直接分析出问题原因,可以尝试跳出出错的代码逻辑,然后梳理代码逻辑,查看崩溃的地址在其余代码中是否使用错误(往往这是根本原因)。

发布了59 篇原创文章 · 获赞 22 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/Martin_chen2/article/details/77651681