C语言,realloc动态内存申请,出现报错double free or corruption (!prev)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言,realloc动态内存申请,出现报错double free or corruption (!prev)相关的知识,希望对你有一定的参考价值。

程序大概如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define MALLOC(num,type) (type*)alloc((num)*sizeof(type))
#define REALLOC(ptr,num,type) (type*)re_alloc(ptr,(num)*sizeof(type))

double *x;
int count =0;
void *alloc(size_t size)

void *new_mem;
new_mem = malloc (size);
if(new_mem == NULL)

printf("Out of memory!\n");
exit(1);

return new_mem;


void *re_alloc(void *ptr, size_t new_size)

void *renew_mem;
renew_mem = realloc(ptr,new_size);
if((renew_mem == NULL)||(renew_mem == ptr))

printf("renew is out of memory\n");
exit(1);

return renew_mem;

void mem_free(void *ptr)

if (ptr != NULL)
free(ptr);


int main()

......
x = MALLOC(N1, double);
for(i=0;i<N1;i++)

x[count] = A; //为x赋值
count ++;


N = N1 +N2;

x = REALLOC(x, N, double);
for(i=0;i<N2;i++)

x[count] = A; //为x赋值
count ++;


mem_free(x);


在linux下运行,报错,但是仍然可以输出正确结果,报错如下:
*** glibc detected *** ./main: double free or corruption (!prev): 0x0000000000cc7910 ***
======= Backtrace: =========
/lib64/libc.so.6[0x395d875366]
/lib64/libc.so.6[0x395d877e93]
/lib64/libc.so.6(fclose+0x14d)[0x395d865add]
./main[0x402a6c]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x395d81ecdd]
./main[0x400a99]
======= Memory map: ========
。。。。。
求帮助,急、、急、、、
加入输出的主程序如下:
int main()

x = MALLOC(N1, double); //其它变量类似
for(i=0;i<N1;i++)

x[count] = A;

y[count] = B;
..... //多个类似的指针变量赋值

count ++;
fprintf(fout, "%12.4f%12.4f\n", x[count], y[count]);


N = N1 +N2;
x = REALLOC(x, N, double); //其它变量类似
for(i=0;i<N2;i++)

x[count] = A;

y[count] = B;

count ++;
fprintf(fout, "%12.4f%12.4f\n", x[count], y[count]);

for(i=0;i<N;i++)

fprintf(fout2, "%12.4f%12.4f\n", x[i], y[i]);


mem_free(x);
mem_free(y);
....

这个错误信息:double free or corruption (!prev),free了多次或者数据损坏。

看了你的代码没有看到明显的多次释放,但是没有看到你输出结果的部分,我想可能是在那部分访问内存越界了。

有时即使越界一个字节也会被检查到而报这个警告。可以仔细检查一下输出部分的代码,或者用先注释掉输出部分,跑一跑以缩小范围这种方法。

while (counter != height - 1)

//此处赋值越界,估计是修改到了动态内存的信息区,造成释放时候取到不正确的信息从而造成崩溃;

假设tom之后的内存就是matrix[0],matrix[1];
tom越界破坏了matrix[N]的一个或者几个记录内存信息的内存,从而造成后果。

参考资料

CSDN.CSDN[引用时间2018-1-8]

参考技术A 这个错误信息:double free or corruption (!prev),free了多次或者数据损坏

看了你的代码没有看到明显的多次释放,但是没有看到你输出结果的部分,我想可能是在那部分访问内存越界了。

有时即使越界一个字节也会被检查到而报这个警告。可以仔细检查一下输出部分的代码,或者用先注释掉输出部分,跑一跑以缩小范围这种方法。追问

你好,注释掉输出后,直接报错 Segmentation fault (core dumped) 加入输出后的程序 见补充问题,求帮助、、、

追答

count ++;
fprintf(fout, "%12.4f%12.4f\n", x[count], y[count]);
问题就在这种地方了,在count++后你才输出,这样在末端妥妥的会越界了
而且你这样根本就是错开了一个单位,数组偏移0的位置就没输出过。

fprintf(fout, "%12.4f%12.4f\n", x[count], y[count]);
count ++;
这样就不会越界

追问

我又看了一下 我的原程序,就是先fprintf(fout, "%12.4f%12.4f\n", x[count], y[count]);
才count++; 上面写错了、、、不好意思啊、、还可能是哪里出错呢?

追答

371行,fclose(fout2);这里多余了
因为你在323行已经关闭过一次了
删掉371行就一切ok

本回答被提问者采纳
参考技术B 你仔细看看你程序中动态分配内存这一句是否有问题:
x = MALLOC(N1, double);
PS:指针!追问

程序的一开始,有如下定义:

#define MALLOC(num,type) (type*)alloc((num)*sizeof(type))
看着没问题啊

追答

看你的程序 你是想把 x作为一个数组吧。
然而请你注意,double *x 这个指针虽然可以指向一个数组,但是它实际上只能作为该数组的第一个元素的地址被调用,也就是说,无论你调用这句命令 x = MALLOC(N1, double);给 x 分配多大的内存,他都只能是存储第一个元素的数据,而不能存储多个元素的数据。而 x 之所以可以作为一个数组的地址指针是因为编译器给数组分配的是几段地址连续的内存空间,你知道了第一个元素的地址
只要相应的将地址变量加1既可以得到第二个元素的地址并访问到第二个元素,同理依次加1就可以得到第三,第四,第五,......第n个元素的地址。
所以,你的程序实际上只分配了存放第一个元素的内存空间只是这块空间很大而已,而其他元素根本没有分配到内存。这就是你的问题所在。

C语言扩展动态内存报错:realloc(): invalid next size: 0x0000000002365010 ***

  晚上被这个内存扩展崩溃的问题折腾的有点崩溃,当答案揭晓的那一刻,恍然大悟,原来如此简单。

  练习题目:输入一个字符串,根据字母进行排序,说白了就是一个简单的冒泡

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#define BUF_LEN 100
#define COUNT 5

int main(void)
{
        char buf[BUF_LEN];
        size_t str_count = 0;
        size_t capacity = COUNT;
        char **pS = calloc(capacity, sizeof(char*));
        char **psTemp = NULL;
        char *pTemp = NULL;
        size_t str_len = 0;
        bool sorted = false;

        printf("Enter strings to be sorted, one per line. Press Enter to end:\n");

        char *ptr = NULL;

        while(true)
        {
                ptr = fgets(buf, BUF_LEN, stdin);
                if(!ptr)
                {
                        printf("Error reading string.\n");
                        free(pS);
                        pS = NULL;
                        return 1;
                }

                if(*ptr == \n)
                        break;

                if(str_count == capacity)
                {
                        capacity += capacity/4;

                        if(!(psTemp = realloc(pS, capacity)))
                                return 1;
                        pS = psTemp;
                }

                str_len = strlen(buf) + 1;

                if(!(pS[str_count] = malloc(str_len)))
                        return 2;
                strcpy(pS[str_count++], buf);
        }

        while(!sorted)
        {
                sorted = true;
                size_t i = 0;
                for(; i < str_count - 1; i++)
                {
                        if(strcmp(pS[i], pS[i+1]) > 0)
                        {
                                sorted = false;
                                pTemp = pS[i];
                                pS[i] = pS[i+1];
                                pS[i + 1] = pTemp;
                        }

                }
        }

        printf("Your input sorted in ascending sequence is:\n\n");
        size_t i = 0;
        for(; i < str_count; i++)
        {
                printf("%s", pS[i]);
                free(pS[i]);
                pS[i] = NULL;
        }
        free(pS);
        pS = NULL;

        return 0;
}

                                     

  上面标黄处,首先是通过calloc进行内存分配,初始是capacity的长度是5,接着判断当输入的字符串个数等于5了,那么就动态的扩展内存,继续按25%的速度增长。就是在扩展这里,一直报错:

*** Error in `./program714.out: realloc(): invalid next size: 0x0000000002365010 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7f5d4)[0x7f476bff35d4]
/lib64/libc.so.6(+0x83bd8)[0x7f476bff7bd8]
/lib64/libc.so.6(realloc+0x1d2)[0x7f476bff9832]
./program714.out[0x4008ea]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f476bf963d5]
./program714.out[0x400729]
======= Memory map: ========
00400000-00401000 r-xp 00000000 fd:01 1321539                            /home/wlf/practice/program714.out
00600000-00601000 r--p 00000000 fd:01 1321539                            /home/wlf/practice/program714.out
00601000-00602000 rw-p 00001000 fd:01 1321539                            /home/wlf/practice/program714.out
02365000-02386000 rw-p 00000000 00:00 0                                  [heap]
7f4764000000-7f4764021000 rw-p 00000000 00:00 0 
7f4764021000-7f4768000000 ---p 00000000 00:00 0 
7f476bd5e000-7f476bd73000 r-xp 00000000 fd:01 655380                     /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f476bd73000-7f476bf72000 ---p 00015000 fd:01 655380                     /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f476bf72000-7f476bf73000 r--p 00014000 fd:01 655380                     /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f476bf73000-7f476bf74000 rw-p 00015000 fd:01 655380                     /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f476bf74000-7f476c136000 r-xp 00000000 fd:01 658657                     /usr/lib64/libc-2.17.so
7f476c136000-7f476c336000 ---p 001c2000 fd:01 658657                     /usr/lib64/libc-2.17.so
7f476c336000-7f476c33a000 r--p 001c2000 fd:01 658657                     /usr/lib64/libc-2.17.so
7f476c33a000-7f476c33c000 rw-p 001c6000 fd:01 658657                     /usr/lib64/libc-2.17.so
7f476c33c000-7f476c341000 rw-p 00000000 00:00 0 
7f476c341000-7f476c363000 r-xp 00000000 fd:01 658372                     /usr/lib64/ld-2.17.so
7f476c557000-7f476c55a000 rw-p 00000000 00:00 0 
7f476c55e000-7f476c562000 rw-p 00000000 00:00 0 
7f476c562000-7f476c563000 r--p 00021000 fd:01 658372                     /usr/lib64/ld-2.17.so
7f476c563000-7f476c564000 rw-p 00022000 fd:01 658372                     /usr/lib64/ld-2.17.so
7f476c564000-7f476c565000 rw-p 00000000 00:00 0 
7ffde3137000-7ffde3158000 rw-p 00000000 00:00 0                          [stack]
7ffde31c5000-7ffde31c7000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted

  代码看来看去发现没毛病,唯一能怀疑的地方就是内存扩展的那一行,经过几番折腾,发现只要一到需要增长调用realloc就报错,最后回去看calloc,只能一拍大腿骂娘了,字节计算的类型不对啊,一个是按char*(相当于二维数组pS[][]中的子数组pS[])来计算字节,一个是按字符(char)来计算字节,得到的内存大小必然不同啊。把realloc的第二个参数加上这个就解决了:  

if(!(psTemp = realloc(pS, capacity*sizeof(char*))))

  编码需谨慎,差之毫厘,谬之千里,一点小小的bug都能让程序崩溃。

以上是关于C语言,realloc动态内存申请,出现报错double free or corruption (!prev)的主要内容,如果未能解决你的问题,请参考以下文章

C语言动态内存管理

通过动态分配创建数组后,在C中通过realloc改变内存大小时出现问题

C++之内存管理:申请与释放

C语言中动态内存分配函数的用法及作用?(比如malloc,calloc,realloc等)

梦开始的地方—— C语言动态内存管理(malloc+calloc+realloc+free)

c/c++动态内存总结