C++ C:双重自由或腐败,可以';找不到错误

C++ C:双重自由或腐败,可以';找不到错误,c++,memory-leaks,valgrind,C++,Memory Leaks,Valgrind,这个错误让我很生气 程序显示,DataPackage::~DataPackage(第40行)中的delete[]导致了问题。但是如果我删除它,程序就会泄漏。 那么,如何修复它?我做错了什么 main.cxx #include "main.h" // currently includes DataPackage.h only DataPackage aTestFunction(){ return DataPackage("hello",5); } int main(){ DataPac

这个错误让我很生气

程序显示,
DataPackage::~DataPackage
(第40行)中的
delete[]
导致了问题。但是如果我删除它,程序就会泄漏。 那么,如何修复它?我做错了什么

main.cxx

#include "main.h" // currently includes DataPackage.h only

DataPackage aTestFunction(){
  return DataPackage("hello",5);
}

int main(){
  DataPackage pack1 = aTestFunction(), pack2 = aTestFunction();
  pack1 = pack2;

  for(unsigned int i = 0; i < pack1.getLength(); i++){
    printf("0x%02x ", *(pack1.getData()+i)&0xff);
  }

  return 0;
}
#include "DataPackage.h" // defines only the class, and private members m_data (char*) and m_length (size_t), includes <cstdio> and <cstring>

DataPackage::DataPackage(){
  m_data = NULL;
  m_length = 0;
}

DataPackage::DataPackage(string data){
  m_data = NULL;
  setData(data.c_str(),data.length()+1);
}

DataPackage::DataPackage(const char *data, size_t length) {
  m_data = NULL;
  setData(data,length);
}

DataPackage::DataPackage(const DataPackage &pack) {
  m_data = NULL;
  setData(pack.m_data,pack.m_length);
}

const char* DataPackage::getData(){
  return m_data;
}

void DataPackage::setData(const char *newdata,size_t newlength){
  char* tmpdata = new char[newlength];
  m_length = newlength;
  memcpy(tmpdata,newdata,m_length);
  delete[] m_data;
  m_data = tmpdata;
}

size_t DataPackage::getLength(){
  return m_length;
}

DataPackage::~DataPackage() {
  delete[] m_data;
}
#include“main.h”//当前仅包括DataPackage.h
数据包aTestFunction(){
返回数据包(“你好”,5);
}
int main(){
数据包pack1=aTestFunction(),pack2=aTestFunction();
pack1=pack2;
for(无符号整数i=0;i
DataPackage.cxx

#include "main.h" // currently includes DataPackage.h only

DataPackage aTestFunction(){
  return DataPackage("hello",5);
}

int main(){
  DataPackage pack1 = aTestFunction(), pack2 = aTestFunction();
  pack1 = pack2;

  for(unsigned int i = 0; i < pack1.getLength(); i++){
    printf("0x%02x ", *(pack1.getData()+i)&0xff);
  }

  return 0;
}
#include "DataPackage.h" // defines only the class, and private members m_data (char*) and m_length (size_t), includes <cstdio> and <cstring>

DataPackage::DataPackage(){
  m_data = NULL;
  m_length = 0;
}

DataPackage::DataPackage(string data){
  m_data = NULL;
  setData(data.c_str(),data.length()+1);
}

DataPackage::DataPackage(const char *data, size_t length) {
  m_data = NULL;
  setData(data,length);
}

DataPackage::DataPackage(const DataPackage &pack) {
  m_data = NULL;
  setData(pack.m_data,pack.m_length);
}

const char* DataPackage::getData(){
  return m_data;
}

void DataPackage::setData(const char *newdata,size_t newlength){
  char* tmpdata = new char[newlength];
  m_length = newlength;
  memcpy(tmpdata,newdata,m_length);
  delete[] m_data;
  m_data = tmpdata;
}

size_t DataPackage::getLength(){
  return m_length;
}

DataPackage::~DataPackage() {
  delete[] m_data;
}
#include“DataPackage.h”//仅定义类,私有成员m_data(char*)和m_length(size_t)包括和
DataPackage::DataPackage(){
m_data=NULL;
m_长度=0;
}
DataPackage::DataPackage(字符串数据){
m_data=NULL;
setData(data.c_str(),data.length()+1);
}
数据包::数据包(常量字符*数据,大小\u t长度){
m_data=NULL;
setData(数据,长度);
}
数据包::数据包(常量数据包和数据包){
m_data=NULL;
setData(pack.m_数据,pack.m_长度);
}
const char*DataPackage::getData(){
返回m_数据;
}
void DataPackage::setData(const char*newdata,size\u t newlength){
char*tmpdata=new char[newlength];
m_长度=新长度;
memcpy(tmpdata、newdata、m_长度);
删除[]m_数据;
m_data=tmpdata;
}
大小\u t数据包::getLength(){
返回m_长度;
}
DataPackage::~DataPackage(){
删除[]m_数据;
}
试试:

void DataPackage::setData(const char *newdata,size_t newlength){
  char* tmpdata = new char[newlength];
  m_length = newlength;
  memcpy(tmpdata,newdata,m_length);

  if (m_data)
  {
      delete[] m_data;
  }

  m_data = tmpdata;
}

从我所看到的情况来看,复制构造函数将m_data设置为NULL,然后调用setData。在setData中,您基本上是在执行delete[]NULL

您需要实现一个赋值操作符来管理
m_数据
。自动生成的实现将只复制指针,而不是复制指向数组的指针。赋值运算符可以如下所示:

DataPackage& DataPackage::operator=(const DataPackage &other) {
   setData(other.m_data, other.m_length);
   return *this;
}

错误是由“pack1=pack2;”引起的在main.cxx中

实现DataPackage::operator=以修复它。

您忘记了,并且没有提供复制分配运算符。因此,当从另一个
数据包中分配一个
数据包时,两个数据包都以指向同一缓冲区的指针结束,并且都尝试删除它


我会扔掉那个类,改用
std::string
std::vector

std::string非常有用,因为后面包含的数据将包含二进制数据(不一定以“\0”结尾)。@michi.0x5d:
string
可以很好地处理任意二进制数据,除非您尝试将其转换为C样式字符串;但是也许向量更合适。谢谢,这解决了它(也许有人会有类似的问题)。但在这种情况下,这可能是一个错误。