我正在尝试在C中重写“ls”命令的精简版本。我最初在我的main()
中完成了所有工作,但工作正常并且没有出现seg故障。我所做的就是将我的主要部分复制并粘贴到一个新函数中,我称之为into_array()
(实际将目录条目保存到我自己的file_info
结构中进行分析稍后的)。现在,当我尝试运行它的晴天代码 - 只是a.out /home
应该排序和打印名称时,我得到完整的排序列表,然后是一个seg错误,因为我唯一改变了直接使用argv[1]
来使用char *pathname
,我假设它与此有关。以下是代码:
void into_array (char *arg)
{
//asume correct input, default
DIR *myDIR;
struct dirent *mydirent;
struct stat *mystat;
myDIR = opendir(arg);
int count = 0;
while ((mydirent = readdir(myDIR)) != NULL)
{
count++;
}
rewinddir(myDIR);
struct file_info **file_info_array = malloc(sizeof(struct file_info*)*count);
int i = 0;
while ((mydirent = readdir(myDIR)) != NULL)
{
stat(arg, mystat);
file_info_array[i] = malloc(sizeof(struct file_info));
struct file_info *file_i = info_store(mydirent, mystat, 's');
file_info_array[i] = file_i;
i++;
}
file_info_array[i] = NULL;
int is_closed = closedir(myDIR);
send_to_sort(file_info_array, 'n');
print(file_info_array);
}
int main (int argc, char *argv[])
{
into_array(argv[1]);
return 0;
}
答案 0 :(得分:3)
这无效:
struct stat *mystat;
...
stat(arg, mystat)
stat
需要指向存储的指针,它可以存储结果,mystat
未初始化。最简单的就是
struct stat mystat;
stat(arg, &mystat)
您正在使用file_info_array[i] = NULL;
写过数组。您还没有为最后一个元素分配存储空间,如果您需要将最后一个元素作为NULL指针,则应为count + 1
元素分配存储空间。
您需要做的其他事情,否则您将自己设置为无法弄清楚代码失败时会发生什么:
答案 1 :(得分:2)
您的原始程序没有段错误并不能证明它完全正确。如果它表现出未定义的行为,那么该行为可以证明是您希望和期望的行为,但是您不能依赖于从运行到运行的相同行为,更不用说在修改代码之后(不解析UB) )。
您的程序包含对您未提供其定义的多个函数的调用。任何这些都可能会调用UB。但是,你提供的函数当然 调用UB:它写入动态数组file_info_array
的末尾,因为你为所有条目分配了足够的空间,但是没有为NULL最后。
正如@nos首先观察到的那样,你也遇到了与变量mystat
相关的问题,并且你的代码非常乐观,假设程序参数是正确的,并且没有任何函数调用失败。