将argv [1]保存到char *变量会导致seg错误传递给单独的函数

时间:2015-09-11 21:47:14

标签: c segmentation-fault argv c-strings readdir

我正在尝试在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;
}

2 个答案:

答案 0 :(得分:3)

这无效:

struct stat *mystat;
 ...

stat(arg, mystat)

stat需要指向存储的指针,它可以存储结果,mystat未初始化。最简单的就是

struct stat mystat;
stat(arg, &mystat)

您正在使用file_info_array[i] = NULL;写过数组。您还没有为最后一个元素分配存储空间,如果您需要将最后一个元素作为NULL指针,则应为count + 1元素分配存储空间。

您需要做的其他事情,否则您将自己设置为无法弄清楚代码失败时会发生什么:

  • opendir()可能会失败,请确保检查它是否成功。
  • stat()可能会失败,请确保检查它是否成功。
  • malloc()可能会失败,请确保检查它是否成功。
  • 有人可能不会将参数传递给您的程序,请检查一下。
  • 您的其他功能中存在同样多的错误,您也应该对其进行审核。

答案 1 :(得分:2)

您的原始程序没有段错误并不能证明它完全正确。如果它表现出未定义的行为,那么该行为可以证明是您希望和期望的行为,但是您不能依赖于从运行到运行的相同行为,更不用说在修改代码之后(不解析UB) )。

您的程序包含对您未提供其定义的多个函数的调用。任何这些都可能会调用UB。但是,你提供的函数当然 调用UB:它写入动态数组file_info_array的末尾,因为你为所有条目分配了足够的空间,但是没有为NULL最后。

正如@nos首先观察到的那样,你也遇到了与变量mystat相关的问题,并且你的代码非常乐观,假设程序参数是正确的,并且没有任何函数调用失败。