指针更改地址
Pointer Changes Address
我一直在创建一个与本地SQLite数据库交互的C++桌面应用程序。我正在使用存储库模式,并将从数据库中检索到的数据存储在类的实例中(用作数据模型)。我已经在我的应用程序的其他地方实现了这种模式,一切正常。但是,似乎在这个特定的实现中,类实例(数据模型)的地址似乎在构造和销毁之间变化。
下面是如何使用我在调试执行期间记录的内存地址设置我的代码的示例...
存储库类 - 构造函数:
目前,我让这个存储库类保持对Configs
数据模型类的控制。这在未来可能会改变,但我目前的想法是易于构建和破坏这个物体(或者我是这么认为的!
ConfigsRepo::ConfigsRepo()
{
this->_configs = new Models::Configs(); // Memory address: 0x039089e8
}
存储库类 - getter 方法:
我省略了数据库连接和 SQL 语句字符串,因为它们有效并且不是问题的一部分。
Models::Configs& ConfigsRepo::Get()
{
int rc = sqlite3_exec("..", "..", &Sql::Convert, &this->_configs, NULL);
// Check rc == SQLITE_OK, blah blah...
return *this->_configs; // Memory address: 0x03908901
}
sql::转换方法:
数据库表中当前只有一行和一列。数据检索正常。
int Sql::Convert(void* ret, int count, char** data, char** columns)
{
// "ret" is a reference to the "Configs" class instance passed
// by the repository.
// Memory address of "ret": 0x03918930 - most likely different
// due to passing by reference.
// Converting retrieved data to a bool and assigning to a
// property of the referenced "Configs" class.
// (if cell equals 1 then 'true', else 'false')
(*(Models::Configs*)ret).SomeProp = atoi(data[0]) == 1;
return 0;
}
存储库类 - 析构函数:
ConfigsRepo::~ConfigsRepo()
{
delete this->_configs; // Memory address: 0x03908901 - exception thrown
this->_configs = NULL;
}
如您所见,"Configs"对象的内存地址在Sql::Convert
回调方法之后发生变化。当析构ConfigsRepo
类(我试图在其中delete this->_configs
)时,会抛出一个异常:Invalid address specified to RtlValidateHeap
。
我不确定为什么内存地址似乎发生了变化,并且我看不到问题。
注意:我开始相信以这种方式调用delete
并不是关于设计模式的好做法,我将在以后重构我的代码。我现在只需要它工作。:)
提前感谢!
查看有关sqlite3_exe(...)
的 sqlite3 文档:
sqlite3_exec() 的第 4 个参数中继到每个回调调用的第一个参数。
因此,在您的函数上:
int rc = sqlite3_exec("..", "..", &Sql::Convert, &this->_configs, NULL);
您实际上是在传递指针指针,即 this->configs 的地址,它本身就是一个指针Models::Configs
在回调站点,您可以将其地址为:
(*(Models::Configs*)ret).SomeProp = atoi(data[0]) == 1;
这是一种令人费解的说法:
(Models::Configs*)ret->SomeProp = atoi(data[0]) == 1;
您可以看到,您并没有撤消在呼叫站点上所做的工作。
所以,我建议你也改变你的sqlite3_exec()
:
int rc = sqlite3_exec("..", "..", &Sql::Convert, this->_configs, NULL);
^^^^^^^^^^^^^^
旁白:你不需要像&Sql::Convert
一样传递Sql::Convert
,就像Sql::Convert
一样
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 将地址分配给本地指针后,公共对象的变量将消失
- 为什么指针不写入类的地址?
- CUDA:统一内存和指针地址的更改
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 如何从绝对地址的 C 样式指针创建对C++对象的引用
- 当我在 C++ 中将派生类的指针分配给指针时,地址会更改
- 是否可以仅通过将分配的指针地址存储在C++中来分析内存?
- 如何在程序集函数中将元素数组作为参数传递时转发 ARM 寄存器的地址指针
- 如何使用构造函数初始化内存地址(指针变量)?
- 数组基础地址指针
- 如何在不使用返回的情况下从函数获取变量的地址(指针)
- 保存QWidgets的地址/指针
- C++ 读取内存地址/指针和偏移量
- 从存储在 CTreeCtrl 的 LPARAM 中的结构中检索地址/指针 (IXMLDOMNode*) - 不起作用
- 简单的C++地址/指针澄清
- 如何获取成员函数的地址指针
- 当“按引用传递”成为强制传递而不是按地址/指针传递时
- C++ 为什么不是同一个地址(指针)