Search code examples
c++clibmysql

libmysql: warning: address of local variable ‘rows’ returned (C++/C)


I'm using g++.

Implemented some wrapper for my convenience to work with libmysql. Also making C/C++ compatible code.

static MYSQL_RES *db_query(MYSQL *db, const char *query, va_list params) {
    char q[500];
    vsprintf(q, query, params);
    va_end(params);
    if (mysql_query(db, q)) {
        fprintf(stderr, "%s\n", mysql_error(db));
        return NULL;
    }

    MYSQL_RES *res = mysql_use_result(db);
    return res;
}

MYSQL_ROW* db_query_all(MYSQL *db, const char* query, ...) {
        va_list params;
    MYSQL_RES *res = db_query(db, query, params);

    int count = mysql_num_rows(res);

    MYSQL_ROW rows[count];
    for (int i = 0; i<count; i++) 
    {
        rows[i] = mysql_fetch_row(res);
    }

    mysql_free_result(res);
    return rows;
}

And getting warning during compilation:

warning: address of local variable ‘rows’ returned [-Wreturn-local-addr]
     MYSQL_ROW rows[count];

Please help me to find what's the problem there. I can't google something relevant to my particular case.


Solution

  • rows is local array to db_query_all function and will be destroyed once control exits the function thus it is undefined behavior to return reference of it.

    You can dynamically allocate the memory and return reference to it.

    MYSQL_ROW* db_query_all(MYSQL *db, const char* query, ...) {
            va_list params;
        MYSQL_RES *res = db_query(db, query, params);
    
        int count = mysql_num_rows(res);
    
        MYSQL_ROW *rows = malloc(sizeof(*rows)*count);
        for (int i = 0; i<count; i++) 
        {
            rows[i] = mysql_fetch_row(res);
        }
    
        mysql_free_result(res);
        return rows;
    }
    

    Note you need to free the memory once done processing.