我正在编写一个动态程序,它将读取Oracle数据库元数据并在内存中构建其结构。
在释放创建为new
的内存以保存Oracle发送给我的数据时,我遇到了问题。该结构放在向量内并运行良好(我可以读取并处理它)。
这是我的代码(数据库内容因为关注问题而被删除):
struct OracleColumnStruct {
std::string name;
ub2 ociType;
FieldType fieldType;
int size;
char *buffer;
sb2 *indicator;
OCIDefine *defineHandler;
};
std::vector<OracleColumnStruct> columns;
void AllocateColumns()
{
columnCount = ... // whatever from database
for (unsigned int i = 0; i < columnCount; i++)
{
ociType = ... // whatever from database
size = ... // whatever from database
OracleColumnStruct data;
data.name = "whatever";
data.ociType = ociType;
data.size = size;
data.buffer = new char[size];
data.indicator = new sb2;
columns.push_back(data);
}
}
void FreeColumns()
{
for (auto &column : columns)
{
if (column.buffer)
delete column.buffer; <<<- Crash here on 2nd interaction
if (column.indicator)
delete column.indicator;
}
}
崩溃讯息:
HEAP CORRUPTION DETECTED: after Normal block (#16497) at 0x00261940.
CRT detected that the application wrote to memory after end of heap buffer.
当我需要释放结构时,它释放第一个元素,在第二个处理中,矢量变为迷失。
删除指针引用是否会混淆整个向量?在那种情况下该怎么办?
答案 0 :(得分:1)
如果你已经以数组形式分配了一些新东西
char* buffer = new char[size];
然后你应该使用删除的数组形式进行删除
delete[] buffer;
答案 1 :(得分:1)
buffer
已分配new[]
,因此必须使用delete[]
而不是delete
释放。
indicator
已分配new
,因此必须使用delete
而不是delete[]
释放。
并且无需检查空值,delete
和delete[]
已经为您处理:
void FreeColumns()
{
for (auto &column : columns)
{
delete[] column.buffer;
delete column.indicator;
}
}
话虽如此,您应该使用std::vector
和std::unique_ptr
,然后您可以完全摆脱FreeColumns()
,只需在需要时拨打columns.clear()
。
struct OracleColumnStruct {
std::string name;
ub2 ociType;
FieldType fieldType;
std::vector<char> buffer;
std::unique_ptr<sb2> indicator;
OCIDefine *defineHandler;
};
void AllocateColumns
{
columnCount = ... // whatever from database
for (unsigned int i = 0; i < columnCount; i++)
{
...
OracleColumnStruct data;
data.name = "whatever";
data.ociType = ociType;
data.buffer.resize(size);
data.indicator.reset(new sb2);
// or: data.indicator = std::make_unique<sb2>();
columns.push_back(data);
...
}
}