【问题标题】:What is the problem using string manipulation functions with MySql?在 MySql 中使用字符串操作函数有什么问题?
【发布时间】:2019-11-01 19:09:48
【问题描述】:

我有一个 MySQL 8.0.17 数据库示例项目,我在 64 位 Windows 机器上使用 Visual Studio CE 2017 进行编译。它是一个控制台应用程序。请参阅下面的样板代码。我遇到的问题是在初始化数据库后尝试操作字符串时。即:取消注释 sprintf_s() 会导致抛出异常。我试图了解这是否是设计使然还是错误?还是我可能做错了什么?

include "pch.h"
include <windows.h> 
include <iostream> 
include <winsock.h> 
include <stdio.h> 
include <mysql.h>

int main()
{   std::cout << "Hello World!\n";
    MYSQL conn;
    MYSQL_RES *res_set;
    MYSQL_ROW row;

    mysql_init(&conn);

    char str[6];
 // sprintf_s(str, 5, "test");

    if(!mysql_real_connect(&conn,"localhost","usr","pas","db",0,NULL,0))
    {   fprintf(stderr, "Connection Failed: %s\n", mysql_error(&conn));
    } else
    {   fprintf(stderr, "Successfully connected to Database.\n");
        int status = mysql_query(&conn, "SELECT * FROM users");
        res_set = mysql_store_result(&conn);
        int count = mysql_num_rows(res_set);
        printf("No of rows = %d\n", count);
        while ((row = mysql_fetch_row(res_set)) != NULL)
        {   for (int i = 0; i < mysql_num_fields(res_set); i++)
            {   printf("%s \t", row != NULL ? row : "NULL");
            } printf("\n");
        }
    }
    mysql_close(&conn);
 // getchar();
    return 0;
}

如果我将 sprintf_s() 放在上面,我觉得很有趣 mysql_init() 它工作得很好吗?那么这是否意味着我需要在每个请求上打开一个新连接?因为它在 5.7 版中不能以这种方式工作,我可以建立连接然后执行多个语句。任何回应都将不胜感激,因为我已经为此苦苦挣扎了一段时间......

以下是编译中包含 sprintf_s() 时调试器在调用 mysql_num_rows() 时抛出的异常...

在 ConsoleApplication1.exe 中的 0x00007FFED78550C0 (libmysql.dll) 处引发异常:0xC0000005:访问冲突读取位置 0x0000000000000000。

因此,我将其精简到尽可能少的行以重现错误:

int main()
{   MYSQL conn;
    MYSQL_RES *res_set;

    mysql_init(&conn);

    char str[50];
    strcpy_s(str, "test");

    if (mysql_real_connect(&conn,"localhost","user","pass","db",0,NULL,0))
    {   int status = mysql_query(&conn, "SELECT * FROM users");
        res_set = mysql_store_result(&conn);
        int count = mysql_num_rows(res_set);  // Exception is thrown here.
    }
    mysql_close(&conn);
}

现在为什么会发生这种情况?谢谢,布赖恩..

【问题讨论】:

  • 该行不应该导致异常。更有可能的是,其他地方存在未定义的行为,并且添加此行会导致编译器发出不同的代码,从而导致 UB 以不同的方式表现出来。
  • 例如,可能的UB:printf("%s \t", row != NULL ? row : "NULL");MYSQL_ROW 不是与 %s 代码兼容的类型,因此这很可能是程序停止的地方。使用调试器——调试器由于异常而停止在哪一行代码上?

标签: c++ mysql windows 64-bit


【解决方案1】:

您没有检查任何行字段是否为 NULL

改为使用

while ((row = mysql_fetch_row(res_set)) != NULL)
{ for (int i = 0; i < mysql_num_fields(res_set); i++)
  {
    printf("%s ", row[i] ? row[i] : "NULL");  
  } 
  printf("\n");
}

【讨论】:

    【解决方案2】:

    感谢那些回答我问题的人。我回滚到 MySQL 5.7 版,它工作正常。也许我尝试采用较新的尖端版本 8.0 有点为时过早。?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-31
      • 1970-01-01
      • 2011-08-26
      • 1970-01-01
      相关资源
      最近更新 更多