由于使用&错误导致的错误代替 *

时间:2016-01-24 04:11:02

标签: c

我正在使用MySQL C API并尝试执行预准备语句以删除行。

   -(void) deleteOne:(int) num
{
    [self initAndConnectSql];
    char copy[30] = "call delete";
    strncat(copy, _name, 15);
    strncat(copy, "(?)", 4);
    MYSQL_STMT * prepared = mysql_stmt_init(&_mysql);
    mysql_stmt_prepare(prepared, copy, strlen(copy));
    MYSQL_BIND bind[1];
    bind[0].buffer_type = MYSQL_TYPE_LONG;
    bind[0].buffer = #
    bind[0].is_null=0;
    bind[0].length= 0;
    if (mysql_stmt_bind_param(prepared, bind))
    {
        printf("error in binding params");
        exit(1);
    }
    if (mysql_stmt_execute(prepared))
    {
        printf("Error executing prepared statement");
        exit(1);
    }
    mysql_stmt_close(prepared);
    mysql_close(&_mysql);
}

此代码工作正常。但是之前当我没有将准备好的变量设置为指针时,我得到了一个被释放的指针,没有在malloc_error_break中设置断点来调试错误。该行是MYSQL_STMT prepared = *mysql_stmt_init(&_mysql);。 我的问题是为什么设置准备作为指针,而不是传入和准备好需要的地方,工作?不应该指针和&是等价的,因为指针存储了它指向的地址和&返回地址,所以对于一个函数,它们是一样的吗?

2 个答案:

答案 0 :(得分:1)

来自manual for mysql_stmt_close

  

关闭准备好的声明。 mysql_stmt_close()也解除了分配   stmt。指向的语句句柄。

如果你这样做:

MYSQL_STMT prepared = *mysql_stmt_init(&_mysql);
mysql_stmt_close(&prepared);

将指向堆栈变量的指针传递到mysql_stmt_close函数,然后尝试free它会导致您看到的错误。相反,您必须传递mysql_stmt_init返回的原始指针,如第一个代码段所示。 mysql_stmt_init返回动态内存(通过malloc或类似函数获取),然后需要mysql_stmt_close释放。

答案 1 :(得分:0)

来自MySQL API

  belongs_to :item

23.8.11.15 mysql_stmt_init() ---------------------------- MYSQL_STMT *mysql_stmt_init(MYSQL *mysql) Description Create a MYSQL_STMT handle. The handle should be freed with mysql_stmt_close(MYSQL_STMT *). 函数将指针返回给mysql_stmt_init()。该部分说它应该被释放"意味着它是从堆动态分配的。返回的值是此堆内存的内存地址(指针)。要正确释放它,必须将相同的内存地址(指针值)赋予MYSQL_STMT

当您使用原始mysql_stmt_close()版本时,您MYSQL_STMT prepared = *mysql_stmt_init(&_mysql);的值复制到位于堆栈中的本地变量MYSQL_STMT中。当您将此地址提供给prepared时,您没有从mysql_stmt_close(&prepared)给出的堆中提供原始内存地址。