C ++在free()中为缓冲区错误分配内存

时间:2018-03-08 13:24:02

标签: c++ memory-management

我需要将这些数据的元组存储到缓冲区中。

"1444394028","1","5339","M","873" 
"1444394028","1","7045","V","0.34902"
"1444394028","1","7042","M","2"
"1444394028","1","7077","V","0.0470588"
"1444394028","1","5415","M","40"

如您所见,记录的长度各不相同。一行等于一条记录。我写过这个函数:

std::string data_string = (record.asString());
char* data =   (char*) malloc (data_string.length() );            
std::copy( data_string.begin(), data_string.end(), data );
data[data_string.length()] = 0;
ressourceBuffer.push_back(data);

现在我可以很好地使用缓冲区,但如果我想释放内存,我会遇到错误。我的自由函数看起来像这样:

/* free memory */
for (const char* b : ressourceBuffer) {
    free ((char*) b);
}

我真的找不到解决方案,而且我的想法已经不多了。它会产生这个错误(这些是堆栈跟踪中大约50行的第一行):

*** Error in `./build-debug/bin/Test': free(): invalid next 
size (fast): 0x00000000019b3cb0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7da1389d97e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7da1389e237a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7da1389e653c]

2 个答案:

答案 0 :(得分:2)

首先,正如评论中已经说过的那样,你不应该在C ++中使用malloc;在某些方面,标准没有考虑它的含义,这可能会使其使用起来很痛苦。使用new,或者最好使用标准容器。同时使用static_cast和同伴进行C风格的演员表。

第二

data[data_string.length()] = 0;

写一个超过缓冲区的末尾。让Ndata_string.length()

char* data = (char*) malloc (data_string.length() );

分配N个字节,索引0N - 1在分配的内存中。因此,N在分配的内存之外。不过,我不能向你保证这是你的问题。

这让我获得第三名:请发布一个最低限度的完整示例。您提供的片段不足以真实地告诉您发生了什么。什么是ressourceBuffer,例如resource是什么。

答案 1 :(得分:0)

您应该将文本行建模为结构:

struct Record
{
  std::string field1; // Rename with column name
  std::string field2;
  std::string field3;
  std::string field4;
}

接下来,重载operator>>以读取记录:

struct Record
{
  //...
  friend std::istream& operator>>(std::istream& input, Record& r);
};
std::istream& operator>>(std::istream& input, Record& r)
{
  // Read column data until the ',' but don't put ',' into string.
  std::getline(input, r.field1, ',');
  std::getline(input, r.field2, ',');
  std::getline(input, r.field3, ',');
  std::getline(input, r.field4);
}

以上允许您使用std::vector创建数据库并简化文件读取:

std::vector<Record> database;
Record r;
while (my_data_file >> r)
{
  database.push_back(r);
}

以上将简化数据库创建。

此外,上面的代码允许您处理可变长度记录。

使用std::vector,您不必关心mallocfreenewdeletestd::vector处理内存分配,因此您不需要。

稍后,您可能希望更改operator>>方法以将数字字段读取为数字,并从字符串中删除"(请参阅std::string::findstd::string::erase)。< / p>