bigcodeszzer
bigcodeszzer

Reputation: 940

C++ valgrind memory loss when deleting?

According to valgrind, I have some serious memory leak errors. The strange thing is, my program doesn't crash when I run it from visual studio. However, when I try to compile on linux, I get a segfault, so I'm guessing there is something wrong.

I commented out most of the code, leaving just the new and the delete[] parts (note, without the new statements, valgrind doesn't have any problems) but the strange thing is, in this test version, I am literally deleting[] /right after/ the new, and valgrind is still complaining about memory leaks.

By theory (as I understand it) this should not be possible. Am I just getting a false positive or have I overlooked something?

Code:

void PosApp::loadRecs() {//.......................This function reads all of the perishable/nonperishable data
    bool mycontinue = true;
    fstream  myfile;
    myfile.open(_filename, ios::in);

    if (!myfile.is_open()) {
        myfile.clear();
        myfile.close();
        myfile.open(_filename, ios::out);
        myfile.close();
        mycontinue = false;
    }


    if (mycontinue) {
        char buffer = '\0'; //Valgrind didn't like it unassigned
        int itemindex = 0;
        Item* myitem;

        while (!myfile.get(buffer).fail()) {// && itemindex <= _noOfItems - 1) {        
            std::cout << std::endl << "buff: " << buffer << std::endl;

            if (buffer == 'N' || buffer == 'P') {
                std::cout << std::endl;
                std::cout << "The Deallocation:" << std::endl
                    << "No of items -1: " << _noOfItems
                    << " >= itemindex: " << itemindex << std::endl;
                if (_noOfItems - 1 >= itemindex) { //unitialized valgrind error (conditional depends on unitialized values)
                    std::cout << std::endl << "going to deallocate  name: " << _items[itemindex]->name() << " at index: " << itemindex << std::endl;
                    delete[] _items[itemindex]; //VALGRIND SAY CANT DO THIS invalid read of size 4
                }
                if (buffer == 'P') {
                    std::cout << std::endl << "going to allocate a perishable";
                    myitem = new Perishable();//new keyword
                    std::cout << std::endl << "DONE allocating a perishable" << std::endl;
                    delete[] myitem;

                }
                else if (buffer == 'N') {//else is extra safe
                    std::cout << std::endl << "going to allocate a nonperishable";
                    myitem = new NonPerishable();
                    std::cout << std::endl << "DONE allocating a nonperishable" << std::endl;
                    delete[] myitem;
                }
                //std::cout << std::endl << "Going to assign " << " at index: " << itemindex << std::endl;
                //myfile.ignore();//.................ignore comma NOTE THIS IS IN WRONG SPOT?
                //myitem->load(myfile);
                //_items[itemindex] = myitem;
                //std::cout << "Assigned  name: " << _items[itemindex]->name() << " at index: " << itemindex << std::endl;
                //itemindex++;  //NoOfItems
            }

        }
        myfile.close();
        _noOfItems = itemindex;//inderect lost blocks



    }

}

Valgrind output:

== 20875 == HEAP SUMMARY :
== 20875 == in use at exit : 656 bytes in 5 blocks
== 20875 == total heap usage : 16 allocs, 16 frees, 10, 869 bytes allocated
== 20875 ==
== 20875 == Searching for pointers to 5 not- freed blocks
== 20875 == Checked 101, 796 bytes
== 20875 ==
== 20875 == 656 bytes in 5 blocks are definitely lost in loss record 1 of 1
== 20875 == at 0x4028C39: operator new(unsigned int) (in / usr / lib / valgrind / vgpreload_memcheck - x86 - linux.so)
== 20875 == by 0x804D6BB : sict::PosApp::run() (PosApp.cpp:403)
== 20875 == by 0x804C1A3 : main(milestone4.cpp:8)
== 20875 ==
== 20875 == LEAK SUMMARY :
== 20875 == definitely lost : 656 bytes in 5 blocks
== 20875 == indirectly lost : 0 bytes in 0 blocks
== 20875 == possibly lost : 0 bytes in 0 blocks
== 20875 == still reachable : 0 bytes in 0 blocks
== 20875 == suppressed : 0 bytes in 0 blocks
== 20875 ==
== 20875 == ERROR SUMMARY : 13 errors from 6 contexts(suppressed : 19 from 8)
== 20875 ==
== 20875 == 1 errors in context 1 of 6 :
    == 20875 == Conditional jump or move depends on uninitialised value(s)
    == 20875 == at 0x4017E9D : strlen(in / lib / ld - 2.14.1.so)
    == 20875 == by 0x636F6C2E : ? ? ?
    == 20875 == Uninitialised value was created by a stack allocation
    == 20875 == at 0x40078F1 : _dl_init_paths(in / lib / ld - 2.14.1.so)
    == 20875 ==
    == 20875 ==
    == 20875 == 1 errors in context 2 of 6 :
    == 20875 == Conditional jump or move depends on uninitialised value(s)
    == 20875 == at 0x4017E93 : strlen(in / lib / ld - 2.14.1.so)
    == 20875 == by 0x636F6C2E : ? ? ?
    == 20875 == Uninitialised value was created by a stack allocation
    == 20875 == at 0x40078F1 : _dl_init_paths(in / lib / ld - 2.14.1.so)
    == 20875 ==
    == 20875 ==
    == 20875 == 2 errors in context 3 of 6 :
    == 20875 == Invalid read of size 4
    == 20875 == at 0x804C70D : sict::PosApp::loadRecs() (PosApp.cpp:132)
    == 20875 == by 0x804D6BB : sict::PosApp::run() (PosApp.cpp:403)
    == 20875 == by 0x804C1A3 : main(milestone4.cpp:8)
    == 20875 == Address 0x43021e4 is 4 bytes before a block of size 148 alloc'd
    == 20875 == at 0x4028C39 : operator new(unsigned int) (in / usr / lib / valgrind / vgpreload_memcheck - x86 - linux.so)
    == 20875 == by 0x804D6BB : sict::PosApp::run() (PosApp.cpp:403)
    == 20875 == by 0x804C1A3 : main(milestone4.cpp:8)
    == 20875 ==
    == 20875 ==
    == 20875 == 3 errors in context 4 of 6 :
    == 20875 == Invalid read of size 4
    == 20875 == at 0x804C7DB : sict::PosApp::loadRecs() (PosApp.cpp:139)
    == 20875 == by 0x804D6BB : sict::PosApp::run() (PosApp.cpp:403)
    == 20875 == by 0x804C1A3 : main(milestone4.cpp:8)
    == 20875 == Address 0x4302ab4 is 4 bytes before a block of size 120 alloc'd
    == 20875 == at 0x4028C39 : operator new(unsigned int) (in / usr / lib / valgrind / vgpreload_memcheck - x86 - linux.so)
    == 20875 == by 0x804D6BB : sict::PosApp::run() (PosApp.cpp:403)
    == 20875 == by 0x804C1A3 : main(milestone4.cpp:8)
    == 20875 ==
    == 20875 ==
    == 20875 == 5 errors in context 5 of 6 :
    == 20875 == Invalid free() / delete / delete[]
    == 20875 == at 0x4027B13 : operator delete[](void*) (in / usr / lib / valgrind / vgpreload_memcheck - x86 - linux.so)
    == 20875 == by 0x804D6BB : sict::PosApp::run() (PosApp.cpp:403)
    == 20875 == by 0x804C1A3 : main(milestone4.cpp:8)
    == 20875 == Address 0x43021e4 is 4 bytes before a block of size 148 alloc'd
    == 20875 == at 0x4028C39 : operator new(unsigned int) (in / usr / lib / valgrind / vgpreload_memcheck - x86 - linux.so)
    == 20875 == by 0x804D6BB : sict::PosApp::run() (PosApp.cpp:403)
    == 20875 == by 0x804C1A3 : main(milestone4.cpp:8)
    == 20875 ==
    --20875--
    --20875--used_suppression : 19 U1004 - ARM - _dl_relocate_object
    == 20875 ==
    == 20875 == ERROR SUMMARY : 13 errors from 6 contexts(suppressed : 19 from 8)

Upvotes: 0

Views: 1298

Answers (2)

Anon Mail
Anon Mail

Reputation: 4770

new should be matched with delete and new[] should be matched with delete[]. Otherwise it's undefined behavior. You seem to being doing delete[] on memory that has been allocated via new.

Upvotes: 3

SergeyA
SergeyA

Reputation: 62563

Here you go:

myitem = new Perishable();//new keyword
delete[] myitem;

You are calling delete[] for something which was not allocated with new[]. That is undefined behaviour and valgrind is correct in complaining.

Upvotes: 3

Related Questions