Бесплатный указатель на символ в c - PullRequest
5 голосов
/ 07 сентября 2010

Я пытаюсь выяснить типы файлов, используя код c, вот код

char *get_file_type(char *path, char *filename)
{
    FILE *fp;
    char command[100];
    char file_details[100];
    char *filetype;

    sprintf(command, "file -i %s%s", path, filename);
    fp = popen(command, "r");
    if (fp == NULL) {
        printf("Failed to run command\n" );
        exit(1);
    }
    while (fgets(file_details,  sizeof(file_details)-1, fp) != NULL) {
         filetype = (strtok(strstr(file_details, " "), ";"));
    }

    pclose(fp);
    return filetype;
}

здесь вместо объявления команды [], могу ли я использовать команду *? Я пытался использовать это, но это бросило исключение. нам не нужно освобождать переменные, объявленные как command []? если да как?

Ответы [ 3 ]

11 голосов
/ 07 сентября 2010

Когда вы объявляете массив:

char command[100];

компилятор выделяет для него память (в данном случае 100 символов), а command указывает на начало этой памяти. Вы можете получить доступ к выделенной памяти:

command[0]  = 'a';  // OK
command[99] = 'A';  // OK
command[100] = 'Z'; // Error: out of bounds

но вы не можете изменить значение command:

command = NULL;     // Compile-time error

Память будет автоматически освобождена, когда command выйдет из области видимости.


Когда вы объявляете указатель:

char *commandptr;

вы создаете только одну переменную для указания на char s, но она еще ни на что не указывает. Попытка использовать его без инициализации это ошибка:

commandptr[0] = 'A';   // Undefined behaviour; probably a segfault

Вам нужно выделить память самостоятельно, используя malloc:

commandptr = malloc(100);
if (commandptr) {
    // Always check that the return value of malloc() is not NULL
    commandptr[0] = 'A';  // Now you can use the allocated memory
}

и освободите его, когда закончите с ним:

free(commandptr);
5 голосов
/ 07 сентября 2010

Вы можете использовать char *command;, но затем вы должны выделить некоторое количество памяти для command для обращения к вызову malloc(), и когда вы закончите с этой памятью, она должна быть снова освобождена вызовом до free().

Как видите, это намного больше работы, чем использование массива фиксированного размера (как вы делаете сейчас), но это также можно сделать намного безопаснее, потому что вы можете создать буфер точно правильного размера вместо того, чтобы надеяться, что общая длина команды не будет превышать 100 символов.

Кроме того, у вашего кода есть проблема: указатель filetype, который возвращает функция, указывает на местоположение в массиве file_details, но этот массив будет очищен компилятором при выполнении оператора return поэтому указатель, возвращаемый функцией, ссылается на некоторую память, помеченную как «свободная для использования в других целях».

Если проблема не в том, что результат get_file_type действителен только для одного файла за раз, вы можете объявить массив file_details как static, чтобы он сохранялся при вызовах функции .

1 голос
/ 07 сентября 2010

Зачем вы это изменили? Для временных буферов люди обычно объявляют массивы с помощью [], поэтому им не нужно беспокоиться об удалении мусора.

...