C编程 - 操作字符串数组时的分段错误

时间:2015-03-17 22:20:15

标签: c arrays string

我正在努力解决当dns变量从大小10变为大小32时发生的分段错误。我相信在main中声明的dns是创建一个包含10个字符串的数组,然后当增加到32时,一个包含32个字符串的数组。

因此,当使用大小为10的dns变量执行时,我得到以字母D开头的4个目录名的输出。这是预期的输出。

如果我将dns变量增加到32,我仍然会获得4个目录名,然后立即获得分段错误。

我编码已经很长时间了,我确信我在某个地方违反了记忆。

非常感谢任何帮助。

谢谢,

void ld_dirs(char *strings[])
{
   int count;
   DIR *dp;
   struct dirent *ep;

   dp = opendir ("/tmp/sysinfo/inputs");
   if (dp != NULL)
   {
      count = 0;

      while (ep = readdir (dp))
      {
         if (ep->d_name[0] == 'D')
         {
            strings[count] = malloc (80 * sizeof(char));
            strings[count] = ep->d_name;
            count ++;
         }
      }

      closedir (dp);
   }
   else
      perror ("Could not open the directory");
}

int main ()
{
   char cwd[120];
   int count, count2;
   char *dns[10];
   char *path;
   if (getcwd(cwd, sizeof(cwd)) != NULL)
      printf ("\nCurrent working directory : %s\n\n\n", cwd);
   else
      perror ("getcwd() error");

   ld_dirs (dns);

   count = 0;

   puts ("List of valid inputs :\n");

   while (dns[count] != NULL)
   {
      puts (dns[count]);
      count ++;
   }     

   printf ("There are %d valid inputs\n", count);
   return 0;
}

2 个答案:

答案 0 :(得分:1)

我立即看到的一个问题是,您将继续为不同的字符串表条目重用readdir的返回值,并覆盖刚刚分配的用于保存名称的地址。但我不认为readdir可以确保为每个调用返回一个新的,已分配的目录条目结构。我怀疑没有,在访问其中一个之前只是时间问题会导致分段错误。

您需要使用readdir

复制每个目录条目中的数据
  while (ep = readdir (dp))
  {
     if (ep->d_name[0] == 'D')
     {
        strings[count] = malloc(80 * sizeof(char));
        //ERROR: strings[count] = ep->d_name;
        strcpy(strings[count], ep->d_name);  //CORRECTED
        count ++;
     }
  }

除此之外,我没有检查其他错误。

答案 1 :(得分:1)

我看到的问题:

  1. 数组大小。

    您已声明:

    char *dns[10];
    

    ld_dirs中没有任何代码,以确保您不会使用strings超出其合法保留的范围。

  2. 您尚未将dirs中的项目初始化为NULL,但您指望在以下NULL循环中项目的值为while

    while (dns[count] != NULL)
    {
       puts (dns[count]);
       count ++;
    }     
    
  3. 您可以通过以下方式解决这些问题:

    1. dns中的项目初始化为NULL

      char *dns[10] = {0};
      
    2. 将数组的大小传递给ld_dir,并确保不要使用超出法律规定的数量。

      将功能界面更改为:

      void ld_dirs(char *strings[], int size)
      

      将通话更改为:

      ld_dirs (dns, sizeof(dns)/sizeof(*dns));