Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;内存泄漏(valgrind)_C++_Memory Leaks_Valgrind_Dynamic Memory Allocation_Delete Operator - Fatal编程技术网

C++ C++;内存泄漏(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

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/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?
    }
}