бесконечный цикл при использовании free () в цикле while - PullRequest
0 голосов
/ 03 октября 2018

Я пишу код, который должен прочитать 512B из файла в буфер, а затем проверить, нашел ли он 3 конкретных байта и был ли true обрыв цикла 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 голосов
/ 03 октября 2018

Вы не можете вернуть указатель на локальную переменную.Как вы решите это, будет зависеть от требуемой семантики.В этом случае объявление magic static разрешит проблему:

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

    ...

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

Хотя, если данные, на которые ссылаются magic и s, не должны изменяться, тогда может быть предпочтительным следующее:

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 )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...