memory leak! how to fix? - c++

Ok, so i'm just learning about memory leaks. i ran valgrind to find memory leaks. i get the following:
==6134== 24 bytes in 3 blocks are definitely lost in loss record 4 of 4
==6134== at 0x4026351: operator new(unsigned int) (vg_replace_malloc.c:255)
==6134== by 0x8048B74: readInput(char&) (in calc)
so does that definitively mean the leak is in my readInput function? if so, how do i get rid of the memory leaks? here's the offending function:
double* readInput(char& command){
std::string in;
std::getline(std::cin, in);
if(!isNumber(in)){
if(in.length()>1){
command = 0;
}
else{
command = in.c_str()[0];
}
return NULL;
}
else{
return new double(atof(in.c_str()));
}
}
thanks!

// ...
return new double(atof(in.c_str()));
// ...
new acquires resource from free store which is being returned. The returned value must be deallocated using delete to avoid memory leak.
If you are calling the function in a while loop, number should be definitely deallocated using delete before running the loop next time. Just using delete once will only deallocate the very last source acquired.
Edit:
// ....
while( condition1 )
{
double *number = NULL ;
number = readInput(command) ;
if( condition2 )
{ .... }
else
{ .... }
delete number ; // Should be done inside the loop itself.
// readInput either returns NULL or a valid memory location.
// delete can be called on a NULL pointer.
}

You're returning a new double... When is that freed? You do call delete on it at some point... right?
Personally, I would recommend just returning non-zero for success and zero for failure and put the value in a double * (or double &) parameter. That way you don't need to bother with new at all.

You return a newly allocated double. Do you delete it somewhere?
Why are you returning a pointer to a newly allocated double? Why not just return a double? It isn't a big deal to return an eight-byte temporary value, and the caller can decide what it wants to do with it (including allocating a new double on the heap if it likes). Assuming the values aren't large, I'd much rather return a temporary. Having the new closer conceptually to the actual use makes the memory management easier.
Moreover, allocating large numbers of very small blocks can lead to inefficient heap use and heap fragmentation, so that the program might run out of memory when it wouldn't otherwise, and might not be able to allocate a large chunk even if it looks like there's plenty left. This may or may not matter (and the extra time needed to allocate memory may or may not matter, especially in a function whose running time is probably dominated by I/O). This is likely micro-optimization, but if there is no good reason for such small allocations you may as well get in the habit of not using them.

Related

Memory leak on deallocating char * set by strcpy?

I have a memory leak detector tool which tells me below code is leaking 100 bytes
#include <string>
#include <iostream>
void setStr(char ** strToSet)
{
strcpy(*strToSet, "something!");
}
void str(std::string& s)
{
char* a = new char[100]();
setStr(&a);
s = a;
delete[] a;
}
int main()
{
std::string s1;
str(s1);
std::cout << s1 << "\n";
return 0;
}
According to this point number 3 it is leaking the amount I allocated (100) minus length of "something!" (10) and I should be leaking 90 bytes.
Am I missing something here or it is safe to assume the tool is reporting wrong?
EDIT: setStr() is in a library and I cannot see the code, so I guessed it is doing that. It could be that it is allocating "something!" on the heap, what about that scenario? Would we have a 90 bytes leak or 100?
This code does not leak and is not the same as point number 3 as you never overwrite variables storing pointer to allocated memory. The potential problems with this code are that it is vulnerable to buffer overflow as if setStr prints more than 99 symbols and it is not exception-safe as if s = a; throws then delete[] a; won't be called and memory would leak.
Updated: If setStr allocates new string and overwrites initial pointer value then the pointer to the 100 byte buffer that you've allocated is lost and those 100 bytes leak. You should initialize a with nullptr prior to passing it to setStr and check that it is not null after setStr returns so assignment s = a; won't cause null pointer dereference.
Summing up all the comments, it is clear what the problem is. The library you are using is requesting a char **. This is a common interface pattern for C functions that allocate memory and return a pointer to that memory, or that return a pointer to memory they own.
The memory you are leaking is allocated in the line char* a = new char[100]();. Because setStr is changing the value of a, you can no longer deallocate that memory.
Unfortunately, without the documentation, we cannot deduce what you are supposed to do with the pointer.
If it is from a call to new[] you need to call delete[].
If it is from a call to malloc you need to call std::free.
If it is a pointer to memory owned by the library, you should do nothing.
You need to find the documentation for this. However, if it is not available, you can try using your memory leak detection tool after removing the new statement and see if it detects a leak. I'm not sure if it is going to be reliable with memory allocated from a library function but it is worth a try.
Finally, regarding the question in your edit, if you leak memory you leak the whole amount, unless you do something that is undefined behavior, which is pointless to discuss anyway. If you new 100 chars and then write some data on them, that doesn't change the amount of memory leaked. It will still be 100 * sizeof(char)

dynamic memory allocation using new with binary search in C++

I am trying to find the maximum memory allocated using new[]. I have used binary search to make allocation a bit faster, in order to find the final memory that can be allocated
bool allocated = false;
int* ptr= nullptr;
int low = 0,high = std::numeric_limits<int>;
while(true)
{
try
{
mid = (low + high) / 2;
ptr = new int[mid];
delete[] ptr;
allocated = true;
}
catch(Exception e)
{....}
if (allocated == true)
{
low = mid;
}else
{
high = low;
cout << "maximum memory allocated at: " << ptr << endl;
}
}
I have modified my code, I am using a new logic to solve this. My problem right now is it is going to a never ending loop. Is there any better way to do this?
This code is useless for a couple of reasons.
Depending on your OS, the memory may or may not be allocated until it is actually accessed. That is, new happily returns a new memory address, but it doesn't make the memory available just yet. It is actually allocated later when and if a corresponding address is accessed. Google up "lazy allocation". If the out-of-memory condition is detected at use time rather than at allocation time, allocation itself may never throw an exception.
If you have a machine with more than 2 gigabytes available, and your int is 32 bits, alloc will eventually overflow and become negative before the memory is exhausted. Then you may get a bad_alloc. Use size_t for all things that are sizes.
Assuming you are doing ++alloc and not ++allocation, it shouldn't matter what address it uses. if you want it to use a different address every time then don't delete the pointer.
This is a particularly bad test.
For the first part you have undefined behaviour. That's because you should only ever delete[] the pointer returned to you by new[]. You need to delete[] pvalue, not value.
The second thing is that your approach will be defragmenting your memory as you're continuously allocating and deallocating contiguous memory blocks. I imagine that your program will understate the maximum block size due to this fragmentation effect. One solution to this would be to launch instances of your program as a new process from the command line, setting the allocation block size as a parameter. Use a divide and conquer bisection approach to attain the maximum size (with some reliability) in log(n) trials.

Potential memory leak?

The following code resolves the problem of removing the duplicate characters in a string.
void removeDuplicatesEff(char *str)
{
if (!str)
return;
int len = strlen(str);
if (len < 2)
return;
const int sz = (1<<CHAR_BIT);
bool hit[sz] = {false};
int tail = 0;
for (int i=0; i<len; ++i)
{
if (!hit[str[i]])
{
str[tail] = str[i];
++tail;
hit[str[i]] = true;
}
}
str[tail] = 0;
}
After setting str[tail]=0 in the last step, if char *str does contain duplicate characters, its size will be smaller, i.e. tail. But I am wondering whether there is a memory leak here? It seems to me that, later, we cannot releasing all the spaces that is allocated to original char *str. Is this right? If so, how can we resolve it in such situations?
It seems to me that, later, we cannot releasing all the spaces that is allocated to original char *str. Is this right?
No. The length of a zero-terminated string is completely decoupled from the size of the allocated memory buffer, and the system treats it separately. As long as every allocation is followed by a symmetrical deallocation (e.g. there’s a free for every malloc operation), you’re safe.
But I am wondering whether there is a memory leak here?
Arguably, yes, this is still a leak since it (temporarily) uses more memory than required. However, that is usually not a problem since the memory gets released eventually. Except in very special circumstances, this would therefore not be considered a leak.
That said, the code is quite unconventional and definitely longer than necessary (it also assumes that CHAR_BIT == 8 but that’s another matter). For instance, you can initialise your flag array much easier, saving a loop:
bool hit[256] = {false};
And why is your loop going over the string one-based, and why is the first character handled separately?
No, there is no leak. You only modify the contents of the array by putting in 0 and not its length.
Also you shouldn't initialize your hit array by assignment with the for-loop. A standard initialization
bool hit[256] = { 0 };
would suffice and can be replaced by your compiler by the most efficient form of initialization.
There is no memory leak in your case. Memory leak happens when you allocate memory from head and not freeing after using it. In your case you are not allocating any memory from heap. You are using local variables which are stored in stack and freed when control returns from that function.
What you are doing is just changing the placement of the terminator character. It doesn't actually change the size of the allocated memory. It's actually a very common operation, and there is no risk of memory leak from doing it.
No, you will not have a memory leak. Performing a delete [] or free() on str will deallocate all allocated memory just fine because that information is stored elsewhere and does not depend on the type of data being stored in str.
But I am wondering whether there is a memory leak here? It seems to me that, later, we cannot releasing all the spaces that is allocated to original char *str
There's probably no problem here. the storage for str has been allocated in one of the following ways:
reserved space on the stack
malloc space on the heap
reserved space in the data segment.
In the first case, all of the space disappears when the stack frame unwinds. In the second case, malloc records the number of bytes allocated (usually in the memory location just before the first byte pointed to by the malloc return value. In the third case, the space is allocated only once when the program is first loaded.
No possibility of a leak there.

Does this produce a memory leak?

I'm following a book on C++ programming, and I'm following the exercises. One exercise asks me to create a program that produces a memory leak. Will this program produce such a leak?
int main()
{
int * pInt = new int;
*pInt = 20;
pInt = new int;
*pInt =50;
return 0;
}
Considering it is a trivial example, not having a delete paired with your new is a leak. In order to prevent a leak in this case you would need the following:
int * pInt = new int;
*pInt = 20;
delete pInt ;
pInt = new int;
*pInt =50;
delete pInt ;
A decent tool to use to detect memory leaks is Valgrind. I ran the tool on your sample code, like so:
valgrind ./a.out
and this is part of the output it produced:
==14153== HEAP SUMMARY:
==14153== in use at exit: 8 bytes in 2 blocks
==14153== total heap usage: 2 allocs, 0 frees, 8 bytes allocated
==14153==
==14153== LEAK SUMMARY:
==14153== definitely lost: 8 bytes in 2 blocks
Which confirms that indeed the program does leak memory.
Yes. To avoid leaks, every time you call new, you have to have a matching call to delete. You have 2 calls to new and no calls to delete, so you have 2 leaks.
Note that when your program exits, the OS will free up all the memory you've allocated with new. So memory leaks are really only a problem for non-trivial programs.
One exercise asks me to create a program that produces a memory leak.
Will this program produce such a leak?
an utter exercise , and your code is a better answer to exercise !
Pointers and memory leaks. These are truly the items that consume most of the debugging time for developers
Memory leak
Memory leaks can be really annoying. The following list describes some scenarios that result in memory leaks.
Reassignment, I'll use an example to explain reassignment.
char *memoryArea = malloc(10);
char *newArea = malloc(10);
This assigns values to the memory locations shown in Figure 4 below.
http://www.ibm.com/developerworks/aix/library/au-toughgame/fig4.gif
Figure 4. Memory locations
memoryArea and newArea have been allocated 10 bytes each and their respective contents are shown in Figure 4. If somebody executes the statement shown below (pointer reassignment )
memoryArea = newArea;
then it will surely take you into tough times in the later stages of this module development.
In the code statement above, the developer has assigned the memoryArea pointer to the newArea pointer. As a result, the memory location to which memoryArea was pointing to earlier becomes an orphan, as shown in Figure 5 below. It cannot be freed, as there is no reference to this location. This will result in a memory leak of 10 bytes.
http://www.ibm.com/developerworks/aix/library/au-toughgame/fig5.gif
Figure 5. Memory leak
Before assigning the pointers, make sure memory locations are not becoming orphaned.
Freeing the parent block first
Suppose there is a pointer memoryArea pointing to a memory location of 10 bytes. The third byte of this memory location further points to some other dynamically allocated memory location of 10 bytes, as shown in Figure 6.
http://www.ibm.com/developerworks/aix/library/au-toughgame/fig6.gif
Figure 6. Dynamically allocated memory
free(memoryArea)
**If memoryArea is freed by making a call to free, then as a result the newArea pointer also will become invalid. The memory location to which newArea was pointing cannot be freed, as there is no pointer left pointing to that location. In other words, the memory location pointed by newArea becomes an orphan and results in memory leak.
Whenever freeing the structured element, which in turn contains the pointer to dynamically allocated memory location, first traverse to the child memory location (newArea in the example) and start freeing from there, traversing back to the parent node.
The correct implementation here will be:
free( memoryArea->newArea);
free(memoryArea);
Improper handling of return values
At time, some functions return the reference to dynamically allocated memory. It becomes the responsibility of the calling function to keep track of this memory location and handle it properly.**
char *func ( )
{
return malloc(20); // make sure to memset this location to ‘\0’…
}
void callingFunc ( )
{
func ( ); // Problem lies here
}
In the example above, the call to the func() function inside the callingFunc() function is not handling the return address of the memory location. As a result, the 20 byte block allocated by the func() function is lost and results in a memory leak.
Sharp Reference at :
http://www.ibm.com/developerworks/aix/library/au-toughgame/
Update:
your interest let me for an edit
Simple rules to avoid Memory Leaks in C
You are allocating memory for p and q:
p=new int [5];
/* ... */
q=new int;
But you are only freeing p using an invalid operator, since arrays should be deleted using delete[]. You should at some point free both p and q using:
delete[] p;
delete q;
Note that since you are making your pointers point to the other pointer's allocated buffer, you might have to check which delete operator corresponds to which new operation.
You should use delete[] on the buffer allocated with new[] and delete with the buffer allocated with new.
Rule 1: Always write “free” just after “malloc”
int *p = (int*) malloc ( sizeof(int) * n );
free (p);
Rule 2: Never, ever, work with the allocated pointer. Use a copy!
int *p_allocated = (int*) malloc ( sizeof(int) * n );
int *p_copy = p_allocated;
// do your stuff with p_copy, not with p_allocated!
// e.g.:
while (n--) { *p_copy++ = n; }
...
free (p_allocated);
Rule 3: Don’t be parsimonious. Use more memory.
Always start by allocating more memory than you need. After you finish debugging, go back and cut on memory use. If you need an array 1000 integers long, allocate 2000, and only after you make sure everything else is OK – only then go back and cut it down to 1000.
Rule 4: Always carry array length along with you
Wherever your array goes, there should go with it it’s length. A nice trick is to allocate an array sized n+1, and save n into it’s 0 place:
int *p_allocated = (int*) malloc ( sizeof(int) * (n+1) );
int *p_copy = p_allocated+1;
p_copy[-1] = n;
// do your stuff with p_copy, not with p_allocated!
free (p_allocated);
Rule 5: Be consistent. And save comments
The most important thing is to be consistent and to write down what you do. I am always amazed at how many programmers seem to think that comments are a waste of time. They are imperative. Without comments, you probably won’t remember what you did. Imagine returning to your code a year after you wrote it, and spending countless hour trying to recall what that index does. Better to spend a couple of seconds writing it down.
Also, if you are consistent, you will not fail often. Always use the same mechanism for passing arrays and pointers. Don’t change the way you do things lightly. If you decide to use my previous trick, use it everywhere, or you might find yourself referring back to a nonexistent place because you forgot what type of reference you chose.
Ref : http://mousomer.wordpress.com/2010/11/03/simple-rules-to-avoid-memory-leaks-in-c/
Yes, this produces not one, but two memory leaks: both allocated ints are leaked. Moreover, the first one is leaked irrecoverably: once you assign pInt a new int the second time, the first allocated item is gone forever.
Will this program produce suck a leak?
Yes, it will.
Yes and no. When pInt is overwritten with a new int pointer, you lose that memory that was previously allocated, however when the program returns, most modern operating systems will clean up this memory, as well as the memory lost by not deallocating pInt at the end.
So in essence, yes, something like this will result in two memory leaks.
It does, because you allocate space with the statement "new int", but do not use "delete" to free the space.

C++ Memory leak

Hi I have this following code, it take nodes from slaveQueue and preload to preload1 and preload2, But the memory is always increasing. I assume it should be released after I call dfs since all the memory should be freed after the local function returns and I checked that pop() function will also free the memory ? so I wonder where is my memory leak? THanks
queue<Graphnode> *preload1 = new queue<Graphnode>;
queue<Graphnode> *preload2 = new queue<Graphnode>;
for(int n = windowWidth; n > 0; n--)
{
if((*slaveQueue).empty())
{
//cout <<"fffffffffffff"<<endl;
break;
}
(*preload2).push((*slaveQueue).front());
//cout << (*slaveQueue).size()<<endl;
(*slaveQueue).pop();
}
int preload1No =0;
while(!(*preload2).empty())
{
preload1No++;
*slaveroot = (*preload2).front();
(*preload2).pop();
if(!(*slaveQueue).empty())
{
(*preload2).push((*slaveQueue).front());
(*slaveQueue).pop();
}
dfs(*slaveroot,goal,totalDepth,*preload1,*preload2,checkfile);
if(preload1No>windowWidth)
{
(*preload1).push(*slaveroot);
(*preload1).pop();
}
else
{
(*preload1).push(*slaveroot);
}
cout<<(*preload1).size()<<"\t"<<(*preload2).size()<<endl;
}
delete slaveroot;
delete preload1;
delete preload2;
delete slaveQueue;
Yes, it will make a copy of the pointer a, but not of the memory that a points to. So there is no memory leak here, and thus nothing to free.
The a in func1 is pass by value, which means its on the stack. Hence it won't create any memory leak. It is released when func exits.
If you are not explicitly allocating any memory in func1, and call no function that does that, then there is no memory leak. All you are copying into the function is a pointer. The copied pointer itself is on the function's stack, and gets popped along with everything else in the function's scope once the function returns.
Your code as shown has no memory leaks.
It does create a copy of a on the stack. But that memory is recovered as soon as the function returns.
If you have a memory leak, that is likely caused by code not shown here.
When you pass a to your function, a copy of a itself is what gets passed. When the function exits, that copy of a gets destroyed. The memory that a points at isn't copied at all in your code.
Your code leaks one byte of memory1 because you're calling func1 in an infinite loop, so the delete a; will never execute. When most people talk/think about memory leaks, however, they're thinking of "progressive" leaks -- ones that leak more memory the longer the program runs.
If you want to get technical, what it leaks is one minimum-sized block from your memory manager. That'll typically be larger than 1 byte, but exactly how much larger will depend on the implementation.