C: вызов stat() стирает строковую переменную?

У меня небольшие проблемы с использованием функции stat в C. Моя цель — реализовать функцию командной строки ls, и я только начинаю свой проект.

Я уже смог распечатать все файлы в моем текущем каталоге, используя что-то вроде:

    env.current_directory = opendir(".");
    while ((env.ent = readdir(env.current_directory)) != NULL)
    {
        stat(env.ent->d_name, &env.infos);
        ft_putstr(env.ent->d_name);
        ft_putchar('\n');
    }
    closedir(env.current_directory);

Итак, это работает нормально. Но этого недостаточно, так как я должен реализовать опции [-Ralrt]. Чтобы иметь дело с сортировкой и т. д., я объявил следующие структуры (это, очевидно, не является окончательным, и, кстати, если вы думаете, что я ввожу себя в заблуждение, я с радостью рассмотрю любую идею: D):

typedef struct s_ent_info       t_ent_info;
struct                          s_ent_info
{
    char                        *name;
    struct stat                 props;
};
typedef struct s_environnement  t_env;
struct                          s_environnement
{
    int                         entity_qty;
    DIR                         *current_directory;
    struct dirent               *current_entity;
    /* struct stat              infos;*/ // This was for testing
    t_ent_info                  **entity;
};

И адаптировал первый метод, выполнив следующие действия:

t_env   env;
int i;

env.entity_qty = i = 0;
env.current_directory = opendir(".");
while ((env.current_entity = readdir(env.current_directory)) != NULL)
    env.entity_qty++;
env.entity = malloc(sizeof(env.entity) * (env.entity_qty + 1));
if (env.entity)
{
    env.entity[env.entity_qty] = NULL;
    rewinddir(env.current_directory);
    while ((env.current_entity = readdir(env.current_directory)) != NULL)
    {
        env.entity[i] = malloc(sizeof(t_ent_info *));
        env.entity[i]->name = ft_set_new_str(env.current_entity->d_name);
        printf("Before i %d name %s adress %p\n", i, env.entity[i]->name, &env.entity[i]->name);
        stat(env.current_entity->d_name, &env.entity[i]->props);
        printf("After i %d name %s adress %p\n", i, env.entity[i]->name, &env.entity[i]->name);
        i++;
    }
}

Как видите, пара printf уже есть, потому что да, вот в чем дело. Вызов printf "До" выводит совершенно обычную строку. А вот "После" - это просто фигня, кроме первого... И я не понимаю, почему, или что я сделал не так (кстати, Я ЗНАЮ, что сделал что-то не так, я просто не понимаю Знаешь что).

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

Before i 0 name . adress 0x7fb4e24000e0
After i 0 name . adress 0x7fb4e24000e0

Before i 1 name .. adress 0x7fb4e24046e0
After i 1 name �8� adress 0x7fb4e24046e0

Before i 2 name .git adress 0x7fb4e2404710
After i 2 name 29� adress 0x7fb4e2404710

...

Кто-нибудь знает?

РЕДАКТИРОВАТЬ :

Я пытался использовать определенный char **, чтобы сохранить имена файлов, думая, что, возможно, stat каким-то образом испортит мою структуру, но это тоже не работает, у меня тот же результат.


person nsierra-    schedule 01.12.2013    source источник
comment
Какой код для ft_set_new_str()?   -  person Scooter    schedule 01.12.2013
comment
Привет спасибо. Вот код для ft_set_new_str() : char *ft_set_new_str(const char *s) { char *set_str; size_t str_size; str_size = ft_strlen(s); set_str = ft_strnew(str_size); /* calls malloc and bzero */ ft_strcpy(set_str, s); return (set_str); } Или pastebin.com/9DACncpa для более удобочитаемой версии.   -  person nsierra-    schedule 01.12.2013


Ответы (1)


Эта строка:

env.entity[i] = malloc(sizeof(t_ent_info *));

Должно быть:

env.entity[i] = malloc(sizeof(t_ent_info));

В настоящее время вы выделяете достаточно места только для указателя t_ent_info - вам нужно выделить размер всей структуры.

person nobody    schedule 01.12.2013
comment
Вау ! Это действительно решило мою проблему! Я действительно думал, что пробовал это... БОЛЬШОЕ спасибо. Но знаете ли вы, почему и как работает функция Before printf? И почему я не получаю ошибку segfault или bus? Ты спас меня, но я все еще в замешательстве! Еще раз спасибо. - person nsierra-; 01.12.2013
comment
Это маловероятно, потому что в большинстве систем выделение памяти и защита происходят на основе полной страницы. Таким образом, если вы запросите 16 байт на типичной машине x86 и получите указатель на 0x00001000, вы сможете записать весь путь до 0x00001fff без ошибок. Но вы испортите память других распределений в этом диапазоне. - person nobody; 01.12.2013
comment
Хорошо, теперь я понял. Интересное (и важное для понимания) поведение. - person nsierra-; 01.12.2013