C基础知识,字符串到指针

时间:2012-02-02 20:45:03

标签: c

我有3个文件的项目。 Common头包含用于检查mysql连接的函数声明:

int conn_check(char **m_error);

主文件调用函数并在出现错误时期望m_error中的某些消息:

if (!conn_check(&m_error)==0)
{
 printf("%s\n", m_error);
}

现在我有问题的功能,因为对指针的了解很少:

int conn_check(char **m_error)
{
int retval = 0;
char mysqlerror[255] = {0};
MYSQL *conn;
conn = mysql_init(NULL);
if (conn)
{
    if (mysql_real_connect(conn, mysql_server, mysql_user_name, mysql_password, "", (ulong)mysql_serverport, mysql_socket, 0)==NULL)
    {
        sprintf(mysqlerror, "%u: %s", mysql_errno(conn), mysql_error(conn));
        *m_error = mysqlerror;  // Problem here
        retval = -1;
    }
} else retval = -2;
mysql_close(conn);
return retval;
}

问题是如何正确地将字符串mysqlerror分配给char指针m_error,以便可以通过mainf中的printf打印错误消息。

4 个答案:

答案 0 :(得分:2)

char **m_error表示您正在将指针传递给指针。大概这是因为函数已经返回int并且您还希望得到错误的文本。实际上,您将堆栈变量的地址分配给您不能执行的指针。

您需要分配内存,将其分配给指针,然后写入:

*m_error = calloc(255, sizeof(char));
snprintf(*m_error, 255, "%u: %s", mysql_errno(conn), mysql_error(conn));

vasprintf()将为您完成所有这些工作:

vasprintf(m_error, "%u: %s", mysql_errno(conn), mysql_error(conn));

请注意,您需要在调用函数中返回free()

答案 1 :(得分:1)

您正在返回指向局部变量的指针(char mysqlerror [255])。您应该在主文件中定义mysqlerror并调用您的函数:

 if (!conn_check(mysqlerror)==0)

并更改原型:

int conn_check(char *mysqlerror)

并删除行:

 char mysqlerror[255] = {0};
 *m_error = mysqlerror;

答案 2 :(得分:1)

conn_check()返回后,如果执行*m_error = mysqlerror;行,那么到那时你最终会得到一个非常可能无效的指针,因为本地字符数组mysqlerror无效在本地功能之外。

你需要传入指向缓冲区的指针并复制字符串,或者使用strdup复制字符串以分配一些全局内存来为你提供返回的有效指针(但是如果这样做的话) ,不要忘记随后使用main()释放free中的记忆。

编辑:如果您选择传入缓冲区,最好传入最大缓冲区大小,因此当您复制字符串时,不会溢出缓冲区。

编辑2:用最少的代码修复现有代码的一种非常黑客的方法当然是将mysqlerror声明为静态,因此它在函数之外是有效的。我不会建议这样做,因为这意味着该函数不是线程安全的。

答案 3 :(得分:1)

这是我的解决方案:

char m_error[255];
if (!conn_check(&m_error)==0)
{
 printf("%s\n", m_error);
}

int conn_check(char **m_error)
{
    int retval = 0;
    char mysqlerror[255];
    MYSQL *conn;
    ...
    sprintf(mysqlerror, "%u: %s", mysql_errno(conn), mysql_error(conn));
    strcopy(*m_error, mysqlerror);
    retval = -1;
    ...
}