*** 检测到 glibc *** free():下一个大小无效(正常):0x0a03c978 *** [重复]

2023-12-21

我正在编写一个套接字程序来下载图像。问题是,当我在 gif 这样的小图片上测试我的代码时,它工作得很好。但是当我用 JPG 图片(大于 GIF)运行它时,我收到错误消息:

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

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

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:程序将图片分成几个文件,然后重新组合,因此组合部分是导致错误的部分。

任何帮助将非常感谢,因为我已经被这个错误困扰超过 3 天了!


您没有验证fopen()呼叫一切成功;这是一个麻烦的根源。

你不检查ftell()给你一个合理的价值lSize.

您没有验证strstr()操作实际上找到了标记字符串。如果不存在,它将返回 NULL,并且接下来的长度操作是假的。但该错误表明您的代码写入越界,而不仅仅是读取数据越界。

您可以将前四个变量声明到循环体中,而不是在循环外部。

您没有显示变量的声明filename;那可能是一个没有分配空间的 char 指针吗?或者它是一个足够大的数组吗?

这是一个赔率的赌注,即某些内容已写入超出某些分配空间的末尾。这段代码有什么问题并不是很明显,但问题可能出在其他地方,但正是这段代码受到了其他地方违规行为的影响。这在记忆问题中很常见;发现问题的代码并不是导致问题的代码。

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

If ftell()返回-1,然后malloc()会分配一个 0 字节的缓冲区,但是fread()将尝试读取最多 4 GB 的数据,这可能会溢出空间。奥托,如果ftell()失败,很可能是fread()也会失败。

你打印出文件的大小了吗?崩溃的是第二个部分文件,还是后来的文件?


我已经获取了您提供的代码,将其包装为main()函数,提供缺少的变量和标头,并在 valgrind 下运行它。 (MacOS X 10.6.6、GCC 4.5.2、Valgrind 3.6.0)显示没有问题。因此,您的问题很可能不在于这段代码本身;程序中较早的其他内容超出了分配的内存范围并导致失败。我使用脚本生成了 4 个部分文件:

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

所以每个文件的长度是 4107 字节。

工作代码

#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;
}

我没有插入所有错误检查,如果这是我自己的程序的话。

我的方案中的输出文件长度为16381字节;即少了 3 个字节。问题在于fwrite()来电。这fread()代码告诉你它读取了多少字节;您减去标头的字节,然后再减去一个。以便if/else代码简化为fwrite() in the else.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

*** 检测到 glibc *** free():下一个大小无效(正常):0x0a03c978 *** [重复] 的相关文章

随机推荐