C初学者问题:指向指针的指针/无法访问函数外部的值

时间:2011-05-14 11:32:04

标签: c function pointers

我正在将一个指向指针(** resultSet)的指针传递给我的MySQL函数。

以下是我如何从函数中复制MySQL数据的摘录:

int
getItems(char * cmd, char **resultSet)
{

...
MYSQL initialisations and set-up
...



    resultSet = malloc(sizeof(char)*(int)mysql_num_rows);

    while((row = mysql_fetch_row(result))) 
    {

            for (i=0 ; i < mysql_num_fields(result); i++)               
            {   
            printf("%i: \t", i);        
            resultSet[counter] = malloc(sizeof(char)*strlen(row[i])+1);
            strcpy(resultSet[counter], row[i]);
            printf("%s\n", resultSet[counter]);
            }
            printf("---------------------\n");
            counter++;      
    }
...
MYSQL cleaning up
...
return 0;
}

使用

主调用它
getItems(cmd, resultSet);

从我的getItems函数中

printf("%s\n", resultSet[0]);

似乎有效。

但是,如果我尝试从我的函数外部访问它,我会遇到分段错误。这是为什么?

5 个答案:

答案 0 :(得分:2)

你可能想要:

resultSet = malloc(sizeof(void *)*(int)mysql_num_rows);

而不是:

resultSet = malloc(sizeof(void)*(int)mysql_num_rows);

因为你需要指针而不是字节。

答案 1 :(得分:1)

如果要将resultSet用作返回参数,则需要进行函数签名

int getItems(char * cmd, char ***resultSet)

并在

这样的函数中使用它
*resultSet = malloc(sizeof(char)*(int)mysql_num_rows)

函数调用可能看起来像

char** results;
nitems = getItems(somecmd, &results); 

更好更简单的可能就是保持原样并在函数调用之前进行分配。

答案 2 :(得分:1)

这里有两个问题:

  • 如上所示,结果集的分配是错误的。
  • 其次,strlen(row [i] +1)将计算row [i] +1引用的内存位置的字符串长度。该长度将比行[i]的字符串长度小1。由于您基本上复制了一个以空字符结尾的字符串,因此请使用该函数:resultSet[counter] = strdup((char *)row[i]);

不需要malloc和strcpy。

答案 3 :(得分:1)

据我所知,您有一组要填充数据的char数组。您的初始分配应更改为:

resultSet = malloc(sizeof(char*)*(int)mysql_num_rows);

反映这一点(通知char *)。

此外:

resultSet[counter] = malloc(sizeof(char)*strlen(row[i])+1);

此行在技术上是正确的,但您应将其更改为:

resultSet[counter] = malloc(sizeof(char) * (strlen(row[i])+1) );

反映你真正想要做的事情(原因是C执行算术的顺序,如果你试图在除char / unsigned char之外的任何其他数据类型上做第一种方法会产生错误的结果)。< / p>

最后,我希望你想以某种方式返回2d数组的值。有两种方法可以做到这一点:

  1. 使函数返回char **(失败时返回NULL)。这里不需要将resultSet作为输入参数。
  2. INT getItems(char * cmd,char *** resultSet)
  3. 请注意,函数中带有resultSet的所有内容都必须更改为* resultSet。然后可以使用以下命令调用该函数:

    char **result;
    int status = getItems(cmd, &result);
    

答案 4 :(得分:0)

您可能只需要将返回值(或参数)设置为&amp; resultSet。但是我们可以确定你是否向函数显示了参数并调用了函数。