在while循环中使用free()时发生无限循环

时间:2018-10-02 21:21:36

标签: c malloc

我正在编写一个代码,该代码应将文件中的512B读入缓冲区,然后检查它是否找到了3个特定字节以及是否从while循环中中断。 我发现我的代码很早,当我发现使用free()从堆中释放缓冲内存时,我陷入了无限循环,因此我正在测试每个子部分。但是我的测试根本不包含缓冲区,当我删除free()然后测试通过并退出循环时,但是我认为我必须在循环中释放缓冲区,以便每次通过时我都可以加载新块。我的代码在这里:

// input: read in a card.raw file
// output: 50 jpg images


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

char* search(char *s);

int main(int argc, char *argv[])
{
    // ensure correct usage
    if (argc != 2)
    {
        fprintf(stderr, "Usage --> recover card.raw\n");
        return 1;
    }

    // try to open a file for reading
    char *infile = argv[1];
    FILE *fp = fopen(infile,"r");
    if (fp == NULL)
    {
        fprintf(stderr,"Can't open file: %s\n", infile);
    }

    // read a 512B block process it and
    char magicNum[3] = {0xff, 0xd8, 0xff};
    char testNum[3] = {0xfa, 0xd8, 0xff};
    char *extractMagicNum = testNum;
    while (extractMagicNum[0] != magicNum[0] || extractMagicNum[1] != magicNum[1] || extractMagicNum[1] != magicNum[1])
    {
        char *buffer = malloc(sizeof(char) * 512);
        fread(buffer, sizeof(char),512, fp);
        // now search buffer for 0xff and when found check next two bytes if magic number break
        printf("I am in while loop\n");
        extractMagicNum = search(buffer);
        // used for checking if return value is right
        for (int i = 0; i < 3; i++)
        {
            printf("%i.Element is %i\n",i,*(extractMagicNum + i));
        }

        free(buffer);
    }

    printf("End...\n");


    // close infile
    fclose(fp);

}

// use bisection search to find 0xff and next two bytes
char* search(char *s)
{
    char magic[3] = {0xff, 0xd8, 0xff};
    char *p = magic;
    // just not to get unused error
    s++;
    s--;
    printf("I am in search \n");

    return p;  //return value should satisfie while condition
}

1 个答案:

答案 0 :(得分:0)

您不能返回指向局部变量的指针。您如何解决该问题将取决于所需的语义。在这种情况下,声明magic为静态将解决此问题:

char* search(char *s)
{
    static char magic[3] = {0xff, 0xd8, 0xff};
    char *p = magic;

    ...

    return p;  //return value should satisfie while condition
}

尽管如果magics所引用的数据不应该更改,则可能首选以下内容:

const char* search( const char* s )
{
    static const char magic[3] = {0xff, 0xd8, 0xff};
    const char* p = magic;

    ...

    return p;  
}

另一个问题是您的while循环无法比较第三个元素。

while( extractMagicNum[0]va != magicNum[0] || 
       extractMagicNum[1] != magicNum[1] || 
       extractMagicNum[1] != magicNum[1] )   // << index should be 2 here perhaps?

还请注意,抑制未使用的变量警告的更简单方法是使用自我分配:s = s ;。编译器很可能会识别该惯用法,并且不会生成任何代码。

关于malloc / free,虽然这些不是导致问题的直接原因,但通过不断分配和释放不变大小的缓冲区来破坏堆毫无用处。只需分配一次缓冲区,然后重复使用:

char *buffer = malloc(512);

while( extractMagicNum[0] != magicNum[0] || 
       extractMagicNum[1] != magicNum[1] || 
       extractMagicNum[2] != magicNum[2] )
{

    ...
}

free(buffer);

您可以这样进一步简化while条件:

while( memcmp( extractMagicNum, 
               magicNum, 
               sizeof(magicNum) ) !=0 )