使用指向字符数组的指针

时间:2011-04-25 20:52:03

标签: c pointers

我想传递一个指向函数指针的指针,在函数中分配内存,用字符串填充它并将其取回,但似乎都没有工作。程序在函数外部不打印。最重要的代码是:

struct record ** getRegEx( int *counter, char** keys )
{
    *counter = 0;
   //get some records, its number is *counter, max lenght of each string is 64

   //COUNTER IS NOT 0! ITS VALUE DEPENDS ON OTHER OPERATIONS I HAVENT WRTTEN HERE
   //...        
    keys =(char ** ) malloc((*counter)*(sizeof(char *)));
    for (j = 0; j < *counter; j++)
    {
      keys[j] = (char* )malloc(64*sizeof(char));            
    }

    strcpy(keys[j],key.dptr);

    printf("size %d : \n", sizeof(**keys));//1
    printf("size %d : \n", sizeof(*keys));//4
    printf("size %d : \n", sizeof(keys[0]));//4
    printf("size %d : \n", sizeof(keys));//4    
   //...
}


/*Out of the function, inside the function OK*/
char**   keys;
int count;  
results = getRegEx(&count, &keys); //&keys or keys - makes no difference
for(int k=0 ; k< *count;k++) //test
{
    printf("keys in db %s: s\n", keys[k]); //nothing!?
}

我已经通过用struct record ** getRegEx( int *counter, char*** keys )(并使用* keys和* keys [i]而不是函数内部的键和键[i]替换函数头来使其工作。谢谢大家!

4 个答案:

答案 0 :(得分:3)

您将零传递给malloc,因此您无法在keys中返回任何内容。

您的for循环永远不会运行。

两者都是因为(*counter)为零。

答案 1 :(得分:2)

  1. 这里有一个严重的问题:

    results = getRegEx(&count, &keys); //&keys or keys - makes no difference
    

    你的评论是错误的 - 它确实有所作为。 keys类型为char **getRegEx期望),&keys类型为char ***

  2. 您的函数具有返回类型,但不返回任何内容。

  3. 您为函数中的keys变量分配动态内存,但函数(正如其编写的)无法传递函数的 out 。您的函数应该是char ***,您应该将其作为&keys传递(如前所述,其类型为char ***。)

  4. 你的大小总是为零,因为你在函数的开头设置了*count = 0(当你不应该在你的函数中设置它时,应该通过{{ 1}}按值而不是指针)。 count的确切效果是实现定义。

  5. 您转换malloc(0)的返回值。这没有错,但在C中是不必要的(如果你真的使用C ++,你应该这么说)并且可以让事情变得更难。

  6. 您永远不会检查malloc的失败返回值。

  7. 在函数声明之外使用malloc指针。在函数调用之外,您应该使用作为参数传递的counter变量。函数参数不会继续存在于它们所使用的函数之外。

答案 2 :(得分:1)

主要问题:

  1. 您的类型不匹配。在对getRegEx(&count, &keys)的调用中,表达式&keys的类型为char ***,而不是char **。请注意,如果要修改keys的值,则必须将指针传递给它。这导致了下一个问题......

  2. 因为您正在修改参数keys的值,而不是它所指向的值,所以您在函数中所做的任何更改都不会反映在调用者中。

  3. 以下是您的代码的修改版本,说明了您正在尝试做的想法

    struct record **getRegEx(int *counter, char ***keys)
    {
       ...
       // type of keys = char ***
       // type of *keys = char **
       // type of **keys = char *
    
       *keys = malloc(*counter * sizeof **keys); // note no cast, operand of sizeof
       if (*keys)
       {
         int j;
         for (j = 0; j < *counter; j++)
         {
           // type of (*keys)[j] == char *
           // type of *(*keys)[j] = char
    
           (*keys)[j] = malloc(64 * sizeof *(*keys)[j]); 
         }
       }
       ...
    }
    

    请注意,我不会投射malloc的结果。从1989年版的C标准开始,您不必这样做,因此可以避免视觉混乱。它还可以保护您免受潜在的错误;如果您忘记在范围中包含stdlib.h或不必为malloc原型,则编译器将假定该函数返回int。如果没有演员表,您将对“不兼容的作业类型”的顺序进行诊断。添加强制转换将会影响诊断,因此您可能会遇到细微(或不那么微妙)的运行时错误。

    另外,请注意我在对象上使用sizeof,而不是类型。同样,这有助于减少视觉混乱,并且如果您决定更改keys的基本类型,它还可以保护您;您也不必更新每个malloc电话。

    为什么(*keys)[j]代替*keys[j]?表达式keys不是数组开头的位置,而是指向该位置。我们必须取消引用keys来获取数组的地址,然后我们将其下标。

答案 3 :(得分:0)

你有一个函数getRegEx,声明它返回struct record **

你知道那个功能缺少什么吗? 任何看起来像return声明的内容!