Memory leaks when allocating struct containing stl vector - c++

I want to allocate memory for a struct that contains std::vector. After allocating it, I will push_back some data to it.
After all, I need to destroy my allocated struct. I want to know how can it be done with no memory corruption.
Here is my code:
typedef struct my_struct_t{
int a, b;
vector<unsigned> vec;
}
} MYSTRUCT;
int main(int argc, const char * argv[])
{
MYSTRUCT* ptr_s = new MYSTRUCT;
for(int i = 0 ; i < 100 ; i++){
ptr_s->vec.push_back(i);
}
ptr_s->vec.clear();
delete ptr_s;
return 0;
}
I tried to use clear as it is supposed to call destructor. But after valgrind-ing my code, there are still some blocks reachable. I also tried to deallocate vector using this:
vector<unsigned>().swap(ptr_s.vec)
But with no success.
output of `valgrind':
==52635== HEAP SUMMARY:
==52635== in use at exit: 10,360 bytes in 5 blocks
==52635== total heap usage: 147 allocs, 142 frees, 25,198 bytes allocated
==52635==
==52635== LEAK SUMMARY:
==52635== definitely lost: 0 bytes in 0 blocks
==52635== indirectly lost: 0 bytes in 0 blocks
==52635== possibly lost: 0 bytes in 0 blocks
==52635== still reachable: 10,360 bytes in 5 blocks
==52635== suppressed: 0 bytes in 0 blocks
==52635== Reachable blocks (those to which a pointer was found) are not shown.
==52635== To see them, rerun with: --leak-check=full --show-leak-kinds=all
Thank you everyone in advance.
update:
I noticed that the source of memory corruption in my application is in somewhere else. So I added an update. Here is the new code:
MYSTRUCT* ptr_s1 = new MYSTRUCT;
MYSTRUCT* ptr_s2 = new MYSTRUCT;
for(int i = 0 ; i < 100 ; i++){
ptr_s1->vec.push_back(i);
}
memcpy(ptr_s2 , ptr_s1, sizeof(*ptr_s1));
delete ptr_s1;
delete ptr_s2; // here I get seg fault
return 0;
As soon as deleting ptr_s2, seg fault happens.
Update: proper way, based on the accepted answer:
typedef struct my_struct_t{
int a, b;
vector<unsigned> vec;
inline my_struct_t operator=(const my_struct_t &s ){
a = s.a;
b = s.b;
vec = s.vec;
return s;
}
} MYSTRUCT;
MYSTRUCT* ptr_s1 = new MYSTRUCT;
MYSTRUCT* ptr_s2 = new MYSTRUCT;
for(int i = 0 ; i < 100 ; i++){
ptr_s1->vec.push_back(i);
}
// no memcpy
// memcpy(ptr_s2 , ptr_s1, sizeof(*ptr_s1));
*ptr_s2 = *ptr_s1;
delete ptr_s1;
delete ptr_s2; // no more sget seg fault
return 0;

You don't need to call std::vector::clear or do something else, the destructor will get called when you delete it via delete ptr_s;.
The still reachable matter is explained in Valgrind FAQ.
My program uses the C++ STL and string classes. Valgrind reports
'still reachable' memory leaks involving these classes at the exit of
the program, but there should be none.
First of all: relax, it's probably not a bug, but a feature. Many
implementations of the C++ standard libraries use their own memory
pool allocators. Memory for quite a number of destructed objects is
not immediately freed and given back to the OS, but kept in the
pool(s) for later re-use. The fact that the pools are not freed at the
exit of the program cause Valgrind to report this memory as still
reachable. The behaviour not to free pools at the exit could be called
a bug of the library though.
Update:
Briefly, don't copy classes with memcpy, if you use memcpy to copy a class object whose destructor deletes a pointer within itself (std::vector member in your case), you will end up with double delete when the second instance of the object is destroyed.
The right way is copy/move constructor and/or assignment operator for classes.

Related

memory leaked when globaly declared?

Is this code still going to leak if instead of declaring the pointers as part of main I declare them globally?
I tested with Valgrind memcheck and it doesn't
class Test1 {
public:
Test1() { std::cout << "Constructor of Test " << std::endl; }
~Test1() { std::cout << "Destructor of Test " << std::endl; }
};
//Memory leaked or not when globally declared?
// Test1 *t1;
// Test1 *t2;
// Test1 *t;
int main()
{
//mem will leak if not deallocated later
Test1 *t1;
Test1 *t2;
Test1 *t;
try {
t1=new Test1[100];
t2=new Test1;
t =new Test1;
throw 10;
}
catch(int i)
{
std::cout << "Caught " << i << std::endl;
// delete []t1;
// delete t;
// delete t2;
}
return 0;
}
Declaring the variable global will make the pointer variable global, not what the pointer points to (which is already global as it is located on the heap).
Therefore, your current implementation also has a leak.
Local variables get destroyed when out of scope, but what they point to is not automatically out. Suggestion: forget completety new and delete operators and use STL or smart pointers.
Edit: You are asking why valgrind does not detect it, this is a different question than the original (I edited to add a tag).
Right now you're always leaking memory, regardless if you're declaring pointers in main or globally.
Whenever you use new in your code, you need to use a delete or delete[].
In modern C++, using new is considered a bad practice, you should be using std::vector, if you want an array, or std::unique_ptr if you're managing a pointer to an object.
As was mentioned already in other answers, the allocated object's destructor will not be called in both variants of your program, the scope and lifetime of the pointers do not influence what happens to the pointees, but you showed that already by printing in the destructor.
Valgrind will report this slightly differently however.
I ran the with a shorter array of 2 elements to reduce the amount of output.
The heap summary, which tells you what data remains on the heap at the end of the run, is the same for both programs:
==397== HEAP SUMMARY:
==397== in use at exit: 12 bytes in 3 blocks
==397== total heap usage: 6 allocs, 3 frees, 76,944 bytes allocated
That means both programs never deallocated the objects.
Valgrind does however make a difference between "definitely lost" allocations, with no reference to the memory blocks remaining in any variable and "still reachable" allocations, where a reference remains.
The leak summary with local pointers
==397== LEAK SUMMARY:
==397== definitely lost: 12 bytes in 3 blocks
==397== indirectly lost: 0 bytes in 0 blocks
==397== possibly lost: 0 bytes in 0 blocks
==397== still reachable: 0 bytes in 0 blocks
==397== suppressed: 0 bytes in 0 blocks
The leak summary with global pointers
==385== LEAK SUMMARY:
==385== definitely lost: 0 bytes in 0 blocks
==385== indirectly lost: 0 bytes in 0 blocks
==385== possibly lost: 0 bytes in 0 blocks
==385== still reachable: 12 bytes in 3 blocks
==385== of which reachable via heuristic:
==385== length64 : 10 bytes in 1 blocks
If the pointers are local, valgrind can be sure that no reference remains, because after main returns, the stack locations are no longer valid.
If the pointers are global, they remain valid and could thus still be used or deallocated.
Why does valgrind make this distinction?
Especially in historic C programs it may be considered legitimate to allocate some memory once and use it throughout the execution, without bothering to later free the memory. The operating system will clean up the whole virtual memory space of the program anyway once the program exits. So while this could be a bug, it could also be intentional.
If you are interested in such leaks, valgrind itself tells you how it must be called to see them:
==405== Reachable blocks (those to which a pointer was found) are not shown.
==405== To see them, rerun with: --leak-check=full --show-leak-kinds=all
"Definitely lost" memory is always suspicious, however, and that is why valgrind distinguished the cases. The value of a tool like valgrind lies in its precision. It is not sufficient to report many actual errors, in order to be useful it must also strive to produce a low number of false positives, otherwise looking at the reports would too often be a waste of developer time.
In modern C++, there are not many excuses for leaking memory, as std::unique_ptr should be the way to allocate dynamic objects. std::vector should be used for dynamic arrays and local objects used wherever possible as the compiler never forgets a deallocation. Even for singletons, the noise in the output of tools like valgrind and address sanitizer usually outweighs the usually minuscule benefits of saving one destructor call or deallocation.

memory leaks and errors in Valgrind

I am a beginner of C++, and still very confused if I correctly freed memories and removed possible dangling pointers. It was one of my school assignments in the past. There were so many students have the same problems, and no one else could help me.
Please identify where I have problems.
==25334== Mismatched free() / delete / delete []
==25334== at 0x4006D21: free (vg_replace_malloc.c:446)
==25334== by 0x80492F2: HashTable::~HashTable() (Hash.c:115)
==25334== by 0x8049145: SymTab::~SymTab() (SymTab.h:9)
==25334== by 0x8048E9D: main (Driver.c:170)
==25334== Address 0x402c0b8 is 0 bytes inside a block of size 12 alloc'd
==25334== at 0x4007862: operator new(unsigned int) (vg_replace_malloc.c:292)
==25334== by 0x8048C73: main (Driver.c:143)
==25334==
==25334==
==25334== HEAP SUMMARY:
==25334== in use at exit: 18 bytes in 4 blocks
==25334== total heap usage: 10 allocs, 6 frees, 106 bytes allocated
==25334==
==25334== 18 bytes in 4 blocks are definitely lost in loss record 1 of 1
==25334== at 0x4007D58: malloc (vg_replace_malloc.c:270)
==25334== by 0x97E96F: strdup (strdup.c:43)
==25334== by 0x8048FDC: UCSDStudent::UCSDStudent(char*, long) (Driver.c:36)
==25334== by 0x8048C92: main (Driver.c:143)
==25334==
==25334== LEAK SUMMARY:
==25334== definitely lost: 18 bytes in 4 blocks
==25334== indirectly lost: 0 bytes in 0 blocks
==25334== possibly lost: 0 bytes in 0 blocks
==25334== still reachable: 0 bytes in 0 blocks
==25334== suppressed: 0 bytes in 0 blocks
==25334==
==25334== For counts of detected and suppressed errors, rerun with: -v
==25334== ERROR SUMMARY: 5 errors from 2 contexts (suppressed: 15 from 8)
Base.h
#ifndef BASE_H
#define BASE_H
#include <iostream>
using namespace std; /* C error */
/* TEMPLATE */
struct Base { /* C++ struct is public class, public methods */
/* PUBLIC SECTION */
/* virtual: candidates for redefinition */
virtual operator char * (void) {
return 0;
}
virtual operator long (void) { // hash function
return 0;
}
virtual long operator == (Base & base) {// isequal function
return *this == base;
}
Base (void) {} // new_element
virtual ~Base (void) {} // delete_element
virtual ostream & Write (ostream & stream) = 0;// write_element
};
#endif
Driver.c
class UCSDStudent : public Base { /* extends Base */
char * name;
long studentnum;
public:
UCSDStudent (char * nm, long sn) :
name (strdup (nm)), studentnum (sn) {} /* Initialization */
~UCSDStudent (void) { /* Destructor */
free (name);
}
Hash.c
/* HashTable constructor */
HashTable :: HashTable (int sz) : size (sz),
table_count(++counter), occupancy (0), table (new Base *[sz]),
probeCount (new int[sz])
HashTable :: ~HashTable (void)
{
/* call function to delete individual elements */
for(int index2 = 0; index2 < size; index2++)
{
if(table[index2] != NULL)
{
free(table[index2]);
table[index2] = NULL;
}
delete table[index2];
}
/*
* delete table itself
* Freed memory
*/
delete[] table;
delete[] probeCount;
/* pointed dangling ptr to NULL */
table = NULL;
probeCount = NULL;
} /* end: ~HashTable */
The two Valgrind errors ("Mismatched free() / delete / delete []" and "18 bytes in 4 blocks are definitely lost") might be related.
In ~HashTable() you call free(table[index2]) which probably means to destroy the UCSDStudent objects (not sure, as you didn't post the whole program, esp. not the code which insert elements into HashTable). I suppose you create UCSDStudent objects with new - and in that case, you also have to use the corresponding destruction method (in this case delete instead of free()). This is the cause for the first Valgrind error.
Furthermore, the free() function will not call the object's destructor, while delete will do that. This would explain why ~UCSDStudent() is not called, causing your program to leak the memory for the student name. So using delete instead of free() in ~HashTable() should solve both errors.
In general, you should try to stay with one way of memory allocation (either malloc()/free() or new/new[]/delete/delete[]). And given that this is a C++ program, new would be the appropriate choice. In the same vein, I'd advise you to remove the strdup() and char* stuff and switch to std::string instead - this would remove another location where you might mix up free() and delete.
You're calling free on memory that appears to have been declared using new, which is the main error coming out of Valgrind there. You also appear to not be following the Rule of Three (although that doesn't appear to be your entire code there).
I would highly recommend you switch to using smart pointers such as std::shared_ptr / std::unique_ptr, and use std::vector / std::array to create containers.
Looks to me like you never call ~UCSDStudent. Unfortunately, it's not possible to tell from the code you have posted, but the destructor itself looks good, so I expect the problem is that the destructor isn't being called.

Can't delete temporary object

I'm resizing and array of objects. I made a temp object but when I don't delete it Valgrind shows memory leaks and an error. Deleting it causes a segfault. Just wondering what Valgrind is complaining about...
void Obj::resize()
{
Obj *temp = new Obj[size * 2]; //<-- line 92
for (int i = 0; i < size; i++)
temp[i] = objarray[i];
delete [] objarray;
objarray = temp;
size *= 2;
//delete temp; //<-- causes segfault
//delete [] temp; // also segfaults, tried them both just in case :\
}
Here's the Valgrind report:
==9292== HEAP SUMMARY:
==9292== in use at exit: 21,484 bytes in 799 blocks
==9292== total heap usage: 3,528 allocs, 2,729 frees, 91,789 bytes allocated
==9292==
==9292== 21,484 (2,644 direct, 18,840 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 4
==9292== at 0x4008409: operator new[](unsigned int) (vg_replace_malloc.c:357)
==9292== by 0x804AC7E: MyClass::resize() (file.cpp:92)
==9292== by 0x804AC34: MyClass::add(int, int) (file.cpp:82)
==9292== by 0x804AAE6: getline(std::istream&, MyClass&) (file.cpp:66)
==9292== by 0x8049772: main (otherfile.cpp:39)
==9292==
==9292== LEAK SUMMARY:
==9292== definitely lost: 2,644 bytes in 1 blocks
==9292== indirectly lost: 18,840 bytes in 798 blocks
==9292== possibly lost: 0 bytes in 0 blocks
==9292== still reachable: 0 bytes in 0 blocks
==9292== suppressed: 0 bytes in 0 blocks
==9292==
==9292== For counts of detected and suppressed errors, rerun with: -v
==9292== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
I'm not too good with gdb, but got this backtrace:
(gdb) run
Starting program:
Program received signal SIGSEGV, Segmentation fault.
0x46ed40e3 in free () from /lib/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.15-58.fc17.i686 libgcc-4.7.2-2.fc17.i686 libstdc++-4.7.2-2.fc17.i686
(gdb) backtrace
#0 0x46ed40e3 in free () from /lib/libc.so.6
#1 0x4742dba0 in operator delete(void*) () from /lib/libstdc++.so.6
#2 0x0804ad68 in MyClass::resize (this=0xbffff28c) at file.cpp:98
#3 0x0804ac35 in MyClass::add (this=0xbffff28c, month=10, day=31)
at file.cpp:82
#4 0x0804aae7 in getline (input=..., a=...) at file.cpp:66
#5 0x08049773 in main (argc=1, argv=0xbffff344) at otherfile.cpp:39
(gdb)
I think that deleting this is bad, because it should just leave the pointer dangling, so it doesn't surprise me that I get a segfault. Still, why would it then cause memory problems? Any ideas would be greatly appreciated.
Indeed, you can't delete it there since you've assigned it to objarray to be used later.
Most likely, you're not deleting objarray in the destructor; or some other function is reassigning it without deleting the old array first.
I would use std::vector rather than a hand-crafted array, to take care of deallocation for me.
If this is the SECOND (or later) time you call resize, then this is a very likely scenario, because you are trying to delete on a heap that has already had a double delete since the temp was already deleted, and now all your objArray writes have gone into a lump of memory that belongs to the heap-management, not to your code.
All sorts of other potential issues may also happen here, such as the memory is now being used for some OTHER object, and it's writing things into the heap memory that you then use as objArray.
You shouldn't delete temp where you are trying to do so. Just don't.
Explicit delete (or delete[]) should only be needed in very low-level library code. Everywhere else you should use smart pointers instead.
Here's a better approach that is (IMO) easier to understand:
std::unique_ptr<Obj[]> temp(new Obj[size * 2]);
// copy stuff from objarray to temp
swap(objarray, temp);
That's it. The unique_ptr destructor will free the old objarray buffer if the swap succeeded. And if an exception was thrown during the copy, it will free the new temporary buffer. In either case objarray (which should also be std::unique_ptr<Obj[]>) is left with a valid buffer.

vector pointer causing valgrind memory leak

I'm trying to learn C++ and valgrind. So I wrote the following code to test it out. But I get some memory leaks. Can anyone explain what's causing the memory leak? Thanks in advance.
#include <vector>
#include <iostream>
using namespace std;
class test
{
int c;
public:
void whatever();
};
void test:: whatever()
{
vector<test*> a;
if(true)
{
test* b = new test();
b->c = 1;
a.push_back(b);
}
test* d = a.back();
cout << "prints: " << d->c;
delete d;
}
int main()
{
test* a = new test();
a->whatever();
return 1;
}
from valgrind
==28548== HEAP SUMMARY:
==28548== in use at exit: 4 bytes in 1 blocks
==28548== total heap usage: 3 allocs, 2 frees, 16 bytes allocated
==28548==
==28548== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==28548== at 0x4C27CC1: operator new(unsigned long) (vg_replace_malloc.c:261)
==28548== by 0x400C36: main (in a.out)
==28548==
==28548== LEAK SUMMARY:
==28548== definitely lost: 4 bytes in 1 blocks
==28548== indirectly lost: 0 bytes in 0 blocks
==28548== possibly lost: 0 bytes in 0 blocks
==28548== still reachable: 0 bytes in 0 blocks
==28548== suppressed: 0 bytes in 0 blocks
==28548==
==28548== For counts of detected and suppressed errors, rerun with: -v
==28548== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
Am I not allowed to delete from a copy of a pointer or am I doing something else wrong?
You never call delete on a.
Of course, the important bit here is that you are using a vector of pointers. Why in the world would you do this? Let the vector take care of memory management for you!
You forgot to delete a; at the end of main().
Note that everything you wrote should never go into real code. You should never use dynamic allocation (new) unless you absolutely have to and know precisely why.
Assuming you want to maintain the vector of pointers for educational purposes, then here's a better way of writing it:
#include <vector>
#include <memory> // for unique_ptr
// intentionally left blank; NO abusing namespace std!
struct Foo
{
int c;
void whatever()
{
std::vector<std::unique_ptr<test>> v;
if (true)
{
v.emplace_back(new test);
v.back()->c = 1;
}
// everything is cleaned up automagically
}
};
int main()
{
Test a; // automatic, not dynamic
a.whatever();
return 1;
}
This is still just for educational purposes; in real life you would try very hard to make do with a plain std::vector<test>, since vector is already a dynamic data structure and there is little need for the extra level of indirection.
The memory leak is in main. You are not deleting the allocated test object.

Possible memory leak using C++ string

Consider the following C++ program:
#include <cstdlib> // for exit(3)
#include <string>
#include <iostream>
using namespace std;
void die()
{
exit(0);
}
int main()
{
string s("Hello, World!");
cout << s << endl;
die();
}
Running this through valgrind shows this (some output trimmed for brevity):
==1643== HEAP SUMMARY:
==1643== in use at exit: 26 bytes in 1 blocks
==1643== total heap usage: 1 allocs, 0 frees, 26 bytes allocated
==1643==
==1643== LEAK SUMMARY:
==1643== definitely lost: 0 bytes in 0 blocks
==1643== indirectly lost: 0 bytes in 0 blocks
==1643== possibly lost: 26 bytes in 1 blocks
==1643== still reachable: 0 bytes in 0 blocks
==1643== suppressed: 0 bytes in 0 blocks
As you can see, there's a possibility that 26 bytes allocated on the heap were lost. I know that the std::string class has a 12-byte struct (at least on my 32-bit x86 arch and GNU compiler 4.2.4), and "Hello, World!" with a null terminator has 14 bytes. If I understand it correctly, the 12-byte structure contains a pointer to the character string, the allocated size, and the reference count (someone correct me if I'm wrong here).
Now my questions: How are C++ strings stored with regard to the stack/heap? Does a stack object exist for a std::string (or other STL containers) when declared?
P.S. I've read somewhere that valgrind may report a false positive of a memory leak in some C++ programs that use STL containers (and "almost-containers" such as std::string). I'm not too worried about this leak, but it does pique my curiosity regarding STL containers and memory management.
Calling exit "terminates the program without leaving the current block and hence without
destroying any objects with automatic storage duration".
In other words, leak or not, you shouldn't really care. When you call exit, you're saying "close this program, I no longer care about anything in it." So stop caring. :)
Obviously it's going to leak resources because you never let the destructor of the string run, absolutely regardless of how it manages those resources.
Others are correct, you are leaking because you are calling exit. To be clear, the leak isn't the string allocated on the stack, it is memory allocated on the heap by the string. For example:
struct Foo { };
int main()
{
Foo f;
die();
}
will not cause valgrind to report a leak.
The leak is probable (instead of definite) because you have an interior pointer to memory allocated on the heap. basic_string is responsible for this. From the header on my machine:
* A string looks like this:
*
* #code
* [_Rep]
* _M_length
* [basic_string<char_type>] _M_capacity
* _M_dataplus _M_refcount
* _M_p ----------------> unnamed array of char_type
* #endcode
*
* Where the _M_p points to the first character in the string, and
* you cast it to a pointer-to-_Rep and subtract 1 to get a
* pointer to the header.
They key is that _M_p doesn't point to the start of the memory allocated on the heap, it points to the first character in the string. Here is a simple example:
struct Foo
{
Foo()
{
// Allocate 4 ints.
m_data = new int[4];
// Move the pointer.
++m_data;
// Null the pointer
//m_data = 0;
}
~Foo()
{
// Put the pointer back, then delete it.
--m_data;
delete [] m_data;
}
int* m_data;
};
int main()
{
Foo f;
die();
}
This will report a probable leak in valgrind. If you comment out the lines where I move m_data valgrind will report 'still reachable'. If you uncomment the line where I set m_data to 0 you'll get a definite leak.
The valgrind documentation has more information on probable leaks and interior pointers.
Of course this "leaks", by exiting before s's stack frame is left you don't give s's destructor a chance to execute.
As for your question wrt std::string storage: Different implementations do different things. Some allocate some 12 bytes on the stack which is used if the string is 12 bytes or shorter. Longer strings go to the heap. Other implementations always go to the heap. Some are reference counted and with copy-on-write semantics, some not. Please turn to Scott Meyers' Effective STL, Item 15.
gcc STL has private memory pool for containers and strings. You can turn this off ; look in valgrind FAQ
http://valgrind.org/docs/manual/faq.html#faq.reports
I would avoid using exit() I see no real reason to use that call. Not sure if it will cause the process to stop instantly without cleaning up the memory first although valgrind does still appear to run.