我有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打印错误消息。
答案 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;
...
}