繁体   English   中英

损坏的结构字符数组 - sqlite C++

[英]Corrupted struct char arrays - sqlite C++

我对这个有点困惑。 到目前为止,使用 SQLite 一切都很好,但现在我试图将查询结果存储在一个简单的结构中。 当我在回调中执行此操作时,我的所有数据在我的 SQLItems 向量中看起来都很棒,但是一旦回调退出,我的 SQLItems 向量就会突然损坏保存我的数据行。 任何想法可能导致这种情况?

// Simple struct to hold column name and row data
struct SQLrow {
    char   * Column;
    char   * Data;
};

// static Vector to hold SQL rows
static std::vector<SQLrow>       SQLItems;

...
// static callback that handles placing query results into structs and into SQLItems vector
// SQLItems column/row data gets corrupted after this function exits
static int countTablesCallback(void *data, int count, char **rows, char **azColName) {
        int i;

        for (i = 0; i < count; i++) {
            SQLrow newItem = { azColName[i] ,rows[i] };
            SQLItems.push_back(newItem);
        }
        *static_cast<std::vector<SQLrow>*>(data) = SQLItems; // Tried this too but throws an exception 
        return 0;
    }

我还认为也许只能从回调静态转换以保存向量,但这也会引发异常。 难倒在这里。 感谢您的任何建议!

你的向量很好, static_cast在那里没有意义,除非data实际上被用作输出参数。 您的问题很可能是SQLrow保存字符指针,而 SQLite 在回调返回后删除指向的字符串。 将您的课程更改为

struct SQLrow {
    std::string Column;
    std::string Data;
};

应该可以解决问题。

仅查看代码,一旦回调返回, rows指向的数据似乎将失效/销毁/更改。 所以你不能保留这些指针供以后使用,并且必须制作数据的副本。

一种简单的方法是将ColumnDatachar *更改为std::string 如果做不到这一点,您将不得不进行某种手动内存管理(用new分配空间,然后稍后删除),这很容易出错,而且现在不太可取。

在我看来,您想要/需要在 C++ 中使用原始字符串的情况很少,而您的情况不是其中之一。 顺便说一句,我希望这会以某种方式帮助您或其他人:

#include <vector>
#include <stdio.h>
#include <string.h>
#include <iostream>


struct SQLrow {
    char* Column;
    char* Data;
};

void your_callback(int count, char **rows, char **azColName) {

    std::vector<SQLrow> rows_list;

    for (int i = 0; i < count; i++) {

        /* Uncomment this if you want 
           your copy of the strings. If you
           use this, don't forget to free the
           memory yourself with delete[] s1 and
           s2.

        size_t s1_len = strlen(rows[i]);
        size_t s2_len = strlen(azColName[i]);

        char* s1 = new char [sizeof(char) * (s1_len + 1)];
        char* s2 = new char [sizeof(char) * (s2_len + 1)];

        memcpy(s1, rows[i], s1_len);
        s1[s1_len] = '\0';

        memcpy(s2, azColName[i], s2_len);
        s2[s2_len] = '\0';

        SQLrow r = { s1, s2 }; */

        SQLrow r = { rows[i], azColName[i] };

        rows_list.push_back(r);
    }

    // test the result
    for (int i = 0; i < count; i++) {
        SQLrow r = rows_list.at(i);

        std::cout << "rows:" << r.Column << " azColName:" << r.Data << std::endl;
    }
}

// this 2 lines are just for simulating the data
// you will get this 'warning: ISO C++ forbids converting a string constant to   char*''
char* rows[] = {"row1", "row2" , "row3" };
char* colName[] = {"name1", "name2", "name3" };

int main()
{
    your_callback(3, rows, colName);

    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM