C中的双指针疑惑

时间:2009-07-22 18:23:48

标签: c pointers

我编写了一个程序,在main函数中我声明了一个指针数组,然后我调用一个函数来拆分给定的句子,然后想把它分配给main()中的指针数组。我无能为力。您能否查看下面粘贴的代码:

   int  main(void)
   {
      char *data[3];

      allocate(data);
      /* Unable to print the strings here */
      printf("Main is %s\n", data[0] );
      printf(""   

   }

   void allocate(char **dt)
   { 
       int i;
       char buf[] = "The great Scorpion";
       char delims[] = " ";

       size_t len;
       char *p;
       char *result = NULL;
       result = strtok(buf," ");
       *dt = result;
       int j = 1;
       while(result!=NULL)
       {   

            result = strtok( NULL, delims );
            dt[j]=result;
            j++;

       }
      /* able to print values here */
      printf( "result is %s\n", dt[0]); 
      printf( "result is %s\n", dt[1] );
      printf( "result is %s\n", dt[2] );
    }

有人可以帮帮我吗?

8 个答案:

答案 0 :(得分:14)

strtok不分配新字符串,它返回指向现有字符串的指针(并使用空字符替换分隔符)。因此,在allocate中,您可以使用dt指针填充buf。由于buf是一个自动变量,因此allocate返回时其生命周期结束,dt中的所有指针都无效。

答案 1 :(得分:2)

如果我没记错的话,strtok()不进行动态分配,它实际上会修改你第一次调用它时传递给它的字符串。因此,在这种情况下,它会修改buf。所以dt是一个指向buf的指针数组。当你退出函数时,buf就会被破坏。

答案 2 :(得分:0)

好的,

  1. 您有一个allocate函数,您可以将返回指针数组传递给它。
    • 在函数内部,您在堆栈上分配一个字符串,然后
    • 在函数
    • 之外创建strtok返回指向此堆栈区域的指针
    • 那时你有'悬挂'指向字符串的指针 - 实际上是
    • 然后调用printf来杀死未分配堆栈中的数据
    • 你错过了printf中的字符串。
  2. 如果你想这样做,正确的方法是 真的allocate函数中分配字符串和
    完成它们后,将它们从主体中释放出来。

    使用strtok的旧方法是在allocate中使用 strdup ,稍后免费使用。


    ... OldStuff 我认为您需要将&data传递给您的allocate功能 不管怎样,或者我还没有醒来。

答案 3 :(得分:0)

实际上你可能只是在你的buf声明中加上static。

答案 4 :(得分:0)

作为一小部分(实际上不会对您的程序产生影响),您的循环结构错误。

   int j = 1;
   while(result!=NULL)
   {   

        result = strtok( NULL, delims );
        dt[j]=result;
        j++;
   }

正确设置dt [0],dt [1]和dt [2]。但是由于你的循环的性质(你检查,调用strtok,然后插入到dt中),你也将NULL分配给dt [3]。在这个简单的例子中,这可能会运行良好,但你可能正在捣毁你的堆栈。你应该真正构建你的循环

   result = strtok(buf," ");
   int j=0
   while(result != NULL)
   {   
        dt[j]=result;
        j++;
        result = strtok(NULL, delims);
   }

答案 5 :(得分:0)

您正在尝试返回本地非静态变量的地址;一旦allocate()函数退出,buf数组就不再存在,因此数据数组中的指针不再指向任何有意义的东西。

您需要做的是保存令牌的副本,而不仅仅是指向它的指针:

void allocate(char **dt)
{
  char buf[] = "The Great Scorpion";
  char delim[] = " ";
  size_t i = 0;
  char *result = strtok(buf, delim);
  while (result)
  {
    dt[i] = malloc(strlen(result) + 1);
    if (dt[i])
    {
      strcpy(dt[i++], result);
    }
    result = strtok(NULL, delim);
  }
}

int main(void)
{
  char *data[3];
  allocate(data);
  ...
}

或者,您可以将数据定义为char的2D数组,而不仅仅是指针数组,但是您需要确保它的大小可以处理最大字符串长度;另外,传递给分配变更的类型:

#define STRING_SIZE ... /* large enough for longest string */
void allocate(char (*dt)[STRING_SIZE+1])
{
  char buf[] = "The Great Scorpion";
  char delim[] = " ";
  size_t i = 0;
  char *result = strtok(buf, delim);
  while (result)
  {
    strcpy(dt[i++], result);
    result = strtok(NULL, delim);
  }
}

int main(void)
{
  char data[3][STRING_SIZE];
  allocate(data);
  ...
}

动态分配内存更灵活,但需要一些簿记,你必须记住在完成后将其释放。

答案 6 :(得分:0)

为了不废弃堆栈,应该使用传递参数“char * data [3]”的大小来保护while循环,在这种情况下为3,即额外参数。

但我同意将静态添加到“static char buf [] = ....”是最快的答案,可以指出已终止函数的解除分配堆栈。

答案 7 :(得分:-1)

您尚未分配要在数据[X]中使用的内存,只分配了数据。

data [0] == null指针