C++ C++;内存泄漏(valgrind)
Valgrind声称我间接地失去了记忆;让我烦恼的是,我不知道为什么会这样 不确定这是假阳性还是我不理解指针赋值之类的 我在这里失忆了吗?若然,原因为何 Valgrind报告:C++ C++;内存泄漏(valgrind),c++,memory-leaks,valgrind,dynamic-memory-allocation,delete-operator,C++,Memory Leaks,Valgrind,Dynamic Memory Allocation,Delete Operator,Valgrind声称我间接地失去了记忆;让我烦恼的是,我不知道为什么会这样 不确定这是假阳性还是我不理解指针赋值之类的 我在这里失忆了吗?若然,原因为何 Valgrind报告: ==24392== 21 bytes in 2 blocks are indirectly lost in loss record 1 of 3 ==24392== at 0x4028699: operator new[](unsigned int) (in /usr/lib/valgrind/vgp
==24392== 21 bytes in 2 blocks are indirectly lost in loss record 1 of 3
==24392== at 0x4028699: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==24392== by 0x804B41D: Perishable::load(std::basic_fstream<char, std::char_traits<char> >&) (Perishable.cpp:42)
==24392== by 0x804C504: sict::PosApp::loadRecs() (PosApp.cpp:139)
==24392== by 0x804D58E: sict::PosApp::run() (PosApp.cpp:393)
==24392== by 0x8049337: main (milestone4.cpp:8)
下面是name()[完全注释]
void Item::name(char *name){
delete[] _name; //..............Just in case it points to something.
//..............Note: How could I possibly be losing memory with this line here??
int x = strlen(name); //........Grab the length of the new input
if (_name == '\0') {//..........If it was empty, ie. its the first assignment
_name = new char[x + 1];//..Allocate the space, +1 for null char
}
for (int i = 0; i < x; i++) {//.Copy
_name[i] = name[i];
}
_name[x] = '\0';//............Yeah, its manual termination. I should maybe use strcpy
}
void Item::name(char*name){
删除[]_name;//………..,以防它指向某些内容。
//注意:我怎么可能会因为这句话而失去记忆??
int x=strlen(name);/…获取新输入的长度
如果(_name=='\0'){/....如果它是空的,即它是第一个赋值
_name=newchar[x+1];/…为空字符分配空间,+1
}
对于(int i=0;i
编辑>>>这是析构函数
Item::~Item() {
std::cout << "called destructor";
delete[] _name;
_name = '\0';
}
Item::~Item(){
std::cout>复制构造函数和赋值运算符
//Copy Constructor
Item::Item(const Item& copyfrom){
(*this) = copyfrom;
}
//Member operators
Item& Item::operator=(const Item &myitem) {
if (!myitem.isEmpty()){
init((*this), myitem._sku, myitem._name, myitem._price, myitem._taxed);
this->_quantity = myitem._quantity;
}
return (*this);
}
void Item::init(Item &obj, char const sku[], char const name[], double priced, bool taxed) {
int length = strlen(name);
int skulength = strlen(sku);
obj._price = priced;
obj._taxed = taxed;
obj._quantity = 0;
obj._name = new char[length+1]; //+1 for the null which wasn't counted. Huge pain debugging that.
for (int i = 0; i < length; i++) {
obj._name[i] = name[i];
if (i < skulength) {//redundanc
obj._sku[i] = sku[i];
}
}
obj._name[length] = '\0';
obj._sku[skulength] = '\0';
}
//复制构造函数
项目::项目(常量项目和复制自){
(*此)=复制自;
}
//成员运算符
项和项::运算符=(常量项和myitem){
如果(!myitem.isEmpty()){
初始((*此),myitem.\u sku,myitem.\u名称,myitem.\u价格,myitem.\u已纳税);
此->\数量=我的项目。\数量;
}
返回(*本条);
}
无效项::初始(项和对象,字符常量sku[],字符常量名称[],双重定价,布尔税){
int length=strlen(名称);
int sku长度=strlen(sku);
对象价格=已定价;
对象已征税=已征税;
对象数量=0;
obj._name=new char[length+1];//+1表示未计数的空字符。调试时非常痛苦。
for(int i=0;i
如果您确实必须使用新的
和裸指针(提示:几乎没有人这样做),那么您需要确保\u name
的所有者在不再需要它时释放它
正确的位置可能是~Item()
析构函数,但是如果没有剩下的代码,就很难确定了。我只看到:
Item::~Item() {
std::cout << "called destructor";
delete[] _name;
// Don't reassign
}
另外,对我来说,使用非常量引用是很可怕的。我认为obj的新命名是最大的问题,没有任何先发制人的检查。这是编译器痛苦地尖叫,试图告诉你使用std::string
。哈哈。可能吧。不幸的是,这是一个学校作业,我不能像那样害羞是否定义了名称?此外,delete[]\u name
看起来很吓人,尤其是当您在之后使用它时(可能是双重释放等)。“\u name=='\0”看起来也非常错误(这应该是==nullptr?还是“\u name[0]='\0'?这显然是删除后未定义的行为…)@bigcodeszzer我敢打赌,您使用给定的相同规则创建自己的类没有任何限制。您不会使用std::string
类,您仍然使用new[]
和delete[]
仅在代码的不同部分。同样,如果您被教导什么是复制构造函数、赋值运算符和析构函数,您仍然可以按照规则正确编写代码。@bigcodeszzer如果您复制或赋值项
对象,那么没有用户定义,您的代码将无法正常工作ined复制构造函数和赋值运算符。您需要向我们展示您在什么上下文中使用项对象。老师说什么都不重要,如果您执行这些操作(赋值、复制构造),您的代码将无法正常工作.因此,如果没有教你这些操作,那就抱怨吧。我很容易导致你的班级基本上做得很少(同样,如果你没有编写所需的操作代码).检查具体是什么?我编辑了答案。如果答案不为空,并且您将其重新设置,则在免费存储区中分配新空间之前,您不会释放旧块。我发现我认为这是相关的。
Item::~Item() {
std::cout << "called destructor";
delete[] _name;
// Don't reassign
}
void Item::init(Item &obj, char const sku[], char const name[], double priced, bool taxed) {
// ...
if (obj._name == nullptr /* 0 */) {
obj._name = new char[length+1];
// What if it's not null?
} else {
// Do you want to delete and new up a char?
}
}