***检测到glibc *** free():下一个大小无效(正常):0x0a03c978 *** [英] *** glibc detected *** free(): invalid next size (normal): 0x0a03c978 ***

查看:97
本文介绍了***检测到glibc *** free():下一个大小无效(正常):0x0a03c978 ***的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个套接字程序来下载图像.问题是,当我在类似gif的小图片上测试代码时,它可以正常工作.但是,当我用JPG图片(大于GIF)运行它时,出现了错误消息:

I'm writing a socket program to download images. The problem is that when I test my code on small pics like gif it works fine. But when I run it with JPG pics (bigger than GIF) I got the error message:

*** glibc detected *** /home/ubuntu/NetBeansProjects/myDownloader/dist/Debug/GNU-Linux-x86/mydownloader: free(): invalid next size (normal): 0x0a03c978 ***

请查看代码,我将提供有关该错误的更多信息.

Please see the code and I'll give more information about the error.

FILE* pFile;
long lSize;
unsigned char* buffer;
size_t result;
FILE* combinedFile = fopen("mypic.jpg", "wb+");

for(i = 1; i <= numberOfPartitions; i++)
{
    sprintf(filename, "part%d", i);
    pFile = fopen(filename, "rb");

    //obtain file size
    fseek(pFile , 0 , SEEK_END);
    lSize = ftell(pFile);
    rewind(pFile);

    // allocate memory to contain the whole file:
    buffer = (unsigned char*) malloc(sizeof(unsigned char) * (lSize + 1));

    if(buffer == NULL)
    {
        fputs("Memory error", stderr);
        exit(2);
    }

    // copy the file into the buffer:
    result = fread(buffer, 1, lSize, pFile);

    if(result != lSize)
    {
        fputs("Reading error", stderr);
        exit(3);
    }
    else
    {
        unsigned char* temp = strstr(buffer, "\r\n\r\n");

        temp = temp + 4;
        int len = lSize - (temp - buffer);

        //printf("i :  %d len is : %d plen is %f\n",i,len,pLen);
        if(i != numberOfPartitions)
            fwrite(temp, 1, len - 1, combinedFile);
        else
            fwrite(temp, 1, len, combinedFile);
    }

    fclose(pFile);
    printf("crash here\n");
    free(buffer);

}

fclose(combinedFile);

我从这部分得到了错误,因为我说当图像尺寸较小时,它可以正常工作.但是更大的尺寸会损坏! P.S:程序将图片分成几个文件,然后重新组合,因此合并部分是导致错误的部分.

I got the error from this part, as i said when the image size is small it works fine. But with bigger size it's broken! P.S: The program divided the pic into several files then re-combine it so the combining part is the one that causes the error.

自从我被这个错误困扰超过3天以来,任何帮助将不胜感激!

Any help will be very much appreciated since I've been stuck with this error for more than 3 days!

推荐答案

您没有验证fopen()调用是否全部成功;这是麻烦的秘诀.

You don't verify that the fopen() calls all succeed; this is a recipe for trouble.

您无需检查ftell()lSize中是否为您提供一个合理的值.

You don't check the ftell() gives you a plausible value in lSize.

您不验证strstr()操作是否确实找到了标记字符串.如果不是这样,它将返回NULL,然后以下长度操作是伪造的.但是该错误表明您的代码已超出范围,而不是仅读取超出范围的数据.

You don't verify that the strstr() operation actually finds the marker string. If it doesn't, it will return NULL and the following length operations are then bogus. But the error suggests that your code has written out of bounds, rather than just read data out of bounds.

您可以将前四个变量声明到循环的主体中,而不是在循环之外.

You could declare the first four variables into the body of the loop instead of outside the loop.

您不显示变量filename的声明;可以是没有分配空间的char指针吗?还是足够大的数组?

You don't show the declaration of the variable filename; could that be a char pointer with no space allocated? Or is it an array that is big enough?

在某些已分配空间的末尾写了一些东西,这是一个赔率的押注.这段代码并没有立即发现任何错误,但是麻烦可能出在其他地方,但正是这段代码在其他地方遭受了违法行为的影响.这在内存问题中很常见.找到问题的代码不是导致问题的代码.

It is an odds-on bet that something has written beyond the end of some allocated space. It is not immediately obvious that there's anything wrong with this code, but the trouble could be elsewhere yet it is this code that suffers the effects of transgressions elsewhere. This is quite common with memory problems; the code that finds the problem isn't the code that causes it.

当分配零字节时,计算机上的malloc()是否返回空指针或非空指针?两者都是合法的回应.

Does the malloc() on your machine return null or a non-null pointer when you allocate zero bytes? Both are legitimate responses.

如果ftell()返回-1,则malloc()将为0字节分配一个缓冲区,但是fread()将尝试读取多达4 GB的数据,这可能会溢出空间. OTOH,如果ftell()失败,则fread()也可能也会失败.

If ftell() returns -1, then malloc() would allocate a buffer for 0 bytes, but the fread() would attempt to read up to 4 GB of data, which might overflow the space. OTOH, if ftell() fails, it is likely that fread() will fail too.

您是否已打印出文件的大小?是第二个崩溃的部分文件还是更高版本的文件?

Have you printed out the sizes of the files? Is it the second partial file that crashes, or a later file?

我已经采用了您提供的代码,将其包装为main()函数,提供了缺少的变量和标头,并在valgrind下运行. (MacOS X 10.6.6,GCC 4.5.2,Valgrind 3.6.0)它没有问题.因此,您的麻烦很可能不在此代码本身内;而是程序中的其他某些内容超出了分配的内存范围,并导致此操作失败.我使用脚本生成了4个零件文件:

I've taken the code you supplied, wrapped it up as a main() function, supplied missing variables and headers, and run it under valgrind. (MacOS X 10.6.6, GCC 4.5.2, Valgrind 3.6.0) It shows no problem. So, your trouble is most probably not in this code per se; something else earlier in your program trampled out of bounds of allocated memory and caused this to fail. I generated the 4 part files using the script:

{ echo "Header:control-Vcontrol-Mreturncontrol-Vcontrol-M"; dd if=/dev/random bs=1k count=4; } >part1

{ echo "Header:control-Vcontrol-Mreturncontrol-Vcontrol-M"; dd if=/dev/random bs=1k count=4; } >part1

每个文件的长度为4107字节.

So each file was 4107 bytes long.

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

int main(void)
{
    char filename[32];
    FILE* pFile;
    long lSize;
    char *buffer;
    ssize_t result;
    FILE* combinedFile = fopen("mypic.jpg", "wb+");
    int numberOfPartitions = 4;
    int i;

    for(i = 1; i <= numberOfPartitions; i++)
    {
        sprintf(filename, "part%d", i);
        pFile = fopen(filename, "rb");

        fseek(pFile , 0 , SEEK_END);
        lSize = ftell(pFile);
        rewind(pFile);
        printf("size(%d) = %ld\n", i, lSize);

        buffer = (char*) malloc(sizeof(char) * (lSize + 1));

        if (buffer == NULL)
        {
            fputs("Memory error", stderr);
            exit(2);
        }

        result = fread(buffer, 1, lSize, pFile);

        if (result != lSize)
        {
            fputs("Reading error", stderr);
            exit(3);
        }
        else
        {
            char* temp = strstr(buffer, "\r\n\r\n");    
            temp = temp + 4;
            int len = lSize - (temp - buffer);
            if(i != numberOfPartitions)
                fwrite(temp, 1, len - 1, combinedFile);
            else
                fwrite(temp, 1, len, combinedFile);
        }

        fclose(pFile);
        printf("crash here\n");
        free(buffer);    
    }

    fclose(combinedFile);
    return 0;
}

如果它是我自己的程序,我并没有插入所有错误检查.

I've not inserted all the error checking that I would if it were my own program.

我的方案中的输出文件长16381个字节;短了3个字节.问题出在fwrite()调用. fread()代码告诉您读取了多少字节.您减去了标头的字节,然后又减去了一个.因此,该if/else代码减少为else中的fwrite().

The output file in my scheme is 16381 bytes long; that is 3 bytes short. The problem there is the fwrite() calls. The fread() code told you how many bytes it read; you subtracted the bytes for the header, and then subtracted one more. So, that if/else code reduces to just the fwrite() in the else.

这篇关于***检测到glibc *** free():下一个大小无效(正常):0x0a03c978 ***的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆