【问题标题】:C : call to stat() erases a string variable?C : 调用 stat() 删除一个字符串变量?
【发布时间】:2013-12-01 01:59:48
【问题描述】:

我在使用 C 中的 stat 函数时遇到了一点问题。 我的目标是实现 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 可能会以某种方式弄乱我的结构,但它也不起作用,我有相同的结果。

【问题讨论】:

  • ft_set_new_str() 的代码是什么?
  • 嗨,谢谢。这是 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 以获得更易读的版本。

标签: c posix stat


【解决方案1】:

这一行:

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

需要:

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

目前您只为 t_ent_info 指针分配了足够的空间 - 您需要分配整个结构的大小。

【讨论】:

  • 哇!这实际上解决了我的问题!我真的以为我已经尝试过了……非常感谢。但是,嘿,您知道“之前” printf 为什么以及如何工作吗?为什么我没有收到段错误或总线错误?你救了我,但我还是很迷茫!再次感谢。
  • 它不太可能崩溃,因为在大多数系统上,内存分配和保护都是在整页的基础上进行的。因此,如果您在典型的 x86 机器上请求 16 个字节并获得指向 0x00001000 的指针,您将能够一直写到 0x00001fff 而不会出错。但是你会破坏该范围内其他分配的内存。
  • 好的,我明白了。有趣(并且需要了解)的行为。
猜你喜欢
  • 1970-01-01
  • 2023-01-28
  • 2021-12-08
  • 2017-08-24
  • 1970-01-01
  • 2012-03-01
  • 1970-01-01
  • 2010-12-23
  • 1970-01-01
相关资源
最近更新 更多