c++ - 函数重新分配c字符串后delete []时出现无效指针错误
问题描述
我正在尝试删除 [] 以前由另一个函数使用“new char []”分配的 c 字符串(char *)。但我得到一个无效的指针错误。
首先是代码
班级:
class myclass
{
public:
myclass(const char*);
~myclass();
char* getNum(const char*, myclass*);
private:
sqlite3* db; //db object
int rc; //int returned by sqlite3 functions
char* zErrMsg; //error message
char* sql; //sql statement
char* num; //<- this is it
static int callback(void*, int, char**, char**);
};
一些功能:
myclass::myclass(const char* filename)
{
//allocating
num = new char[2];
num[0] = 'i';
num[1] = '\0';
//connect to sqlite db using filename
}
char* myclass::getNum(const char* id, myclass* obj) //obj will be passed to callback function
{
std::cout<<"getNum"<<std::endl;
std::cout<<static_cast<void *>(&num[0])<<"("<<num[0]<<")"<<std::endl; //test1. writes address and first char. all seems ok
delete[] num; //here is the problem
num = new char[10];
strcpy(num, "not found");
std::cout<<static_cast<void *>(&num[0])<<"("<<num[0]<<")"<<std::endl; //test2. writes same address as test1 and first char. all seems ok
//sql query construction. Nothing wrong here.
//next query gets executed and callback function gets called.
rc = sqlite3_exec(db, query, callback, static_cast<void*>(obj), &zErrMsg);
return num; //returns num from db. "not found" otherwise
}
int myclass::callback(void* obj, int argc, char** argv, char** azColName)
{
std::cout<<"callback"<<std::endl;
myclass* const object = static_cast<myclass*>(obj);
std::cout<<static_cast<void *>(&object->num[0])<<"("<<object->num[0]<<")"<<std::endl; //test3. writes same address as test2 and first char. all seems ok
delete[] object->num; //no problems here
object->num = new char[strlen(argv[0])+1]; //address of num changes
object->num = argv[0];
std::cout<<static_cast<void *>(&object->num[0])<<"("<<object->num[0]<<")"<<std::endl; //test4. writes different address and first char. But all seems ok.
return 0;
}
关于回调:似乎 sqlite3_exec() 想要一个静态回调函数。所以它看不到“myclass”的“num”成员,因为它不是静态的。而且我不能使它成为静态的,因为我需要它用于其他成员函数。所以我将对象地址传递给 in 并使用 -> 来访问它的成员。
主要的:
int main(int argc, char const *argv[])
{
myclass a(filename);
a.getNum("id", &a) //works first time
a.getNum("id", &a) //doesn't work
return 0;
}
getNum() 的第一次调用完成了工作。没有错。第二个(在第一次回调修改 num 之后)我得到一个无效的指针错误。
它发生在 getNum 函数内的第一个 delete[] 上。如果我尝试在它之前输出 num - 一切正常并且我得到正确的输出。
我知道它与回调函数内部的重新分配有关,但我不明白是什么。我必须动态重新分配它,因为我不知道从 db 返回的值的长度。我在 getNum 中取消分配它,因为我不想要任何内存泄漏。如果我删除该释放(在 getNum 内),程序似乎可以完美运行(但可能存在内存泄漏?)。
我
解决方案
在您的回调中,您将 num 从不是通过 new 分配的 sqlite 重新分配给 argv[0]。
object->num = new char[strlen(argv[0])+1]; //address of num changes
object->num = argv[0]; // <--- here
你可能的意思是:
object->num = new char[strlen(argv[0])+1]; //address of num changes
strcpy (object->num, argv[0]);
推荐阅读
- azure - 使用证书获取令牌时,对象引用未设置为对象的实例
- powershell - 如何使用 Powershell 按顺序打印 PDF 文件?
- node.js - node-canvas registerFont 部署后找不到字体文件(在本地工作)
- flutter - 如何在调用构建方法之前等待异步方法完成加载数据?
- android - 在现有应用程序上集成 Flutter
- python - Python列表 - 获取非唯一值的特定索引
- cmake - CMake - Eigen3_DIR-NOTFOUND
- r - R:计算时间序列中列值的百分比
- awk - AWK 使用 if-then 和 AND/OR 运算符打印匹配字符串
- bixby - 如何从结果视图中引用外部概念的价值?