Sqlite3和pthread,双自由或损坏(out)
Sqlite3 and pthread, double free or corruption (out)
我试图创建一个连接到数据库的线程,从那里获取一些数据并打印到控制台。问题是,当线程完成时抛出异常:
双倍空闲或损坏(出) 中止(转储核心)
我尝试使用sqlite3和pthread,但这两个并不是真正的朋友。
我想,但我不确定问题是否来自数据库类。
有人知道是什么导致了异常吗?这是我的代码:链接
数据库类:
class Database {
private:
sqlite3 *db;
static int CallBack(void *data, int argc, char **argv, char **azColName)
{
int index = 0;
char** dataToReturn = new char*[1000];
while (dataToReturn[index])
{
index++;
}
for (int i = index; i < argc + index; i++)
{
dataToReturn[i] = (char *)malloc(sizeof(char) * sizeof(argv[i - index]));
strcpy((dataToReturn)[i], argv[i - index]);
}
return 0;
}
public:
char **Select()
{
char *zErrMsg = 0;
int rc;
rc = sqlite3_open("test.db", &db);
if (rc)
{
fprintf(stderr, "Can't open database: %sn", sqlite3_errmsg(db));
exit(1);
}
else
{
fprintf(stderr, "Opened database successfullyn");
}
char **data;
int rc2 = sqlite3_exec(db, "SELECT * FROM SHARED_FILE", CallBack, data, &zErrMsg);
if (rc2 != SQLITE_OK)
{
sqlite3_free(zErrMsg);
exit(2);
}
sqlite3_close(db);
return data;
}
线程函数:
static void FunctioForThread()
{
printf("start");
auto database = new Database();
char** returnData = database->Select();
printf("something from db: %s n", returnData[0]);
printf("stop");
}
static void *threadd(void *arg)
{
pthread_detach(pthread_self());
fflush(stdout);
FunctioForThread();
}
以及主要功能:
int main()
{
pthread_t thread;
char arg[100] = "test";
pthread_create(&thread, NULL, &threadd, arg);
while(1);
}
您正在取消引用((char **)data)[index]
中传递给CallBack
的data
,但其值是通过sqlite3_exec
的回调从Select
中的data
传递的。Select
中的data
在中分配
char **data = (char **)malloc(0);
不允许取消引用指向零长度分配的指针。还要注意,零大小的malloc
的行为是由实现定义的,因此应该避免它(C++中的malloc
无论如何都应该优先于new
)。
编辑后:
现在data
是从Select
返回的,从未写入,但随后在中被取消引用
returnData[0]
在CCD_ 14中。这是不明确的行为。
此外,sizeof(argv[i - index])
不会返回argv[i - index]
所指向的字符串的长度。它将返回指针类型的大小。因此,您的分配可能会太小,再次出现未定义的行为。使用std::strlen
获取以零结尾的字符串的长度。
则指针argv[i - index]
也可以是NULL
以指示返回行中的NULL
值(参见sqlite3_exec
的文档)。在这种情况下,来自它的strcpy
也将是未定义的行为。
循环while (dataToReturn[index])
将导致未定义的行为,因为为dataToReturn
分配了一个数组,但从未设置其元素。即使设置了值,请注意,当且仅当C样式字符串dataToReturn[index]
指向的长度为零时,条件才成立。如果在分配的范围内不存在这样的字符串,那么行为也是未定义的。
您也有内存泄漏,因为您从未free
任何malloc
ed数据,并且因为dataToReturn
在每次回调调用结束时都会被丢弃,所以它不是很有用。
没有充分的理由使用所有这些C样式构造。使用new
代替malloc
,std::string
和std::vector
代替char
阵列,std::cout
和std::cerr
代替printf
和fprintf(stcerr, ...
,std::thread
代替pthreads
。唯一需要考虑的是C库的接口边界。
- 为什么会发生堆损坏
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 平均图像时图像损坏
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 为什么C中的通用链表中存储的数据已损坏
- IN, OUT, INOUT Parameters
- gdb错误:Backtrace已停止:上一帧与此帧相同(堆栈已损坏?)
- 即使使用调试编译标志,表达式也是"optimized out"
- C++双重释放或损坏(out)
- 捕获标准输出以压缩并使用 CTRL-C 中断会给出损坏的 zip 文件
- 使用全局声明的向量时,C++双重释放错误/损坏
- 赋值运算符上的双重释放或损坏(out)
- IPIV magma_getrs_gpu上的双免费或损坏(OUT)
- Sqlite3和pthread,双自由或损坏(out)
- 字符指针指向字符串,然后指向字符串数组。"./a.out"中的错误:malloc():内存损坏:0x0900c3b0***
- c++双重释放或损坏(out)错误
- C++:双倍免费或损坏(out)
- c++双精度释放或损坏(out):即使使用复制构造函数和赋值操作符
- "./a.out"中的错误:双重释放或损坏(!prev):0x096fb008***中止(核心转储)
- 析构函数给出我不明白的输出("./a.out"中的错误:双重释放或损坏(快速顶部):)