关于MySQL C API参考的是这个教程MySQL C API programming,按照上述教程新建一个文件check_mysql.c

#include <mysql.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  printf("MySQL client version: %s\n", mysql_get_client_info());

  exit(0);
}

使用gcc编译

gcc -g -std=c11 -Wall -Wextra -Werror check_mysql.c -o check_mysql `mysql_config --cflags --libs`

添加-g来使用valgrind调试,添加-std=c11来制定C标准,然后运行valgrind --leak-check=full ./check_mysql

==6034== Memcheck, a memory error detector
==6034== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6034== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6034== Command: ./check_mysql
==6034== 
MySQL client version: 5.7.35
==6034== 
==6034== HEAP SUMMARY:
==6034==     in use at exit: 0 bytes in 0 blocks
==6034==   total heap usage: 2 allocs, 2 frees, 73,728 bytes allocated
==6034== 
==6034== All heap blocks were freed -- no leaks are possible
==6034== 
==6034== For counts of detected and suppressed errors, rerun with: -v
==6034== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

没有问题

新建一个createdb.c

#include <mysql.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  MYSQL *con = mysql_init(NULL);

  if (con == NULL)
  {
      fprintf(stderr, "%s\n", mysql_error(con));
      exit(1);
  }

  if (mysql_real_connect(con, "localhost", "root", "root_passwd",
          NULL, 0, NULL, 0) == NULL)
  {
      fprintf(stderr, "%s\n", mysql_error(con));
      mysql_close(con);
      exit(1);
  }

  if (mysql_query(con, "CREATE DATABASE testdb"))
  {
      fprintf(stderr, "%s\n", mysql_error(con));
      mysql_close(con);
      exit(1);
  }

  mysql_close(con);
  exit(0);
}

编译后运行

==6198== Memcheck, a memory error detector
==6198== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6198== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6198== Command: ./check_mysql
==6198== 
==6198== 
==6198== HEAP SUMMARY:
==6198==     in use at exit: 8,408 bytes in 4 blocks
==6198==   total heap usage: 4,578 allocs, 4,574 frees, 303,326 bytes allocated
==6198== 
==6198== 56 bytes in 1 blocks are possibly lost in loss record 1 of 4
==6198==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6198==    by 0x4EA04AF: ??? (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20.3.22)
==6198==    by 0x4E9F4FC: ??? (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20.3.22)
==6198==    by 0x4E5EC24: mysql_server_init (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20.3.22)
==6198==    by 0x4E67646: mysql_init (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20.3.22)
==6198==    by 0x1088AB: main (check_mysql.c:7)
==6198== 
==6198== 176 bytes in 1 blocks are possibly lost in loss record 2 of 4
==6198==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6198==    by 0x4EA04AF: ??? (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20.3.22)
==6198==    by 0x4E9E688: ??? (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20.3.22)
==6198==    by 0x4E70D33: ??? (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20.3.22)
==6198==    by 0x4E5EC2B: mysql_server_init (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20.3.22)
==6198==    by 0x4E67646: mysql_init (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20.3.22)
==6198==    by 0x1088AB: main (check_mysql.c:7)
==6198== 
==6198== LEAK SUMMARY:
==6198==    definitely lost: 0 bytes in 0 blocks
==6198==    indirectly lost: 0 bytes in 0 blocks
==6198==      possibly lost: 232 bytes in 2 blocks
==6198==    still reachable: 8,176 bytes in 2 blocks
==6198==         suppressed: 0 bytes in 0 blocks
==6198== Reachable blocks (those to which a pointer was found) are not shown.
==6198== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==6198== 
==6198== For counts of detected and suppressed errors, rerun with: -v
==6198== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

出现了内存泄漏。

之前我按照教程写自己代码的时候以为是我的问题,所以修改了很久都没有解决。后来在stackoverflow上找到了一个相同的问题:Valgrind Possibly Lost - MYSQL,原来是没有在mysql_close()后面接mysql_library_end()

原因是mysql_init()会隐式执行mysql_library_init()mysql_close()没有执行mysql_library_end()

标签: none

评论已关闭