I have the following code
void foo()
{
char* pcBlock = new char[1000];
...
delete[] pcBlock;
...
pcBlock = new char[100000];
...
delete[] pcBlock;
}
Would the code below result in a memory leak?
void foo()
{
char* pcBlock = new char[1000];
...
pcBlock = new char[100000];
...
delete[] pcBlock;
}
Yes, there's likely a memory leak if you don't delete[] pcBlock in the first .... Reassigning a pointer does not automatically delete what it previously pointed to.
Operator "new" and "delete" should be used in pairs. Otherwise, using "new" without "deleting" causes memory leakage.
Yes, the previously allocated 1000 bytes are not freed and pcBlock is replaced with new set of memory. There is no way to release the previous 1000 bytes. So its a mem leak.
Yes, it will most likely leak memory (unless the compiler is smart enough to fix that for you, but most won't).
Maybe you should try to realloc in some way.
Yes, it will. Probably you think that the arrays will overlap and delete therefore will free the first array, but in fact they are allocated to different parts of memory.
YES IT WOULD CAUSE MEMORY LEAK
In C++ there is one simple rule:
Every call of new should end with call of delete at the end.
And every new[] -> with delete[]. Otherwise you will get memory leak.
C++ is language where programmer should control dynamic memory by himself (or using 3rd-party libs).
Related
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)
I am trying to build a stack that resizes itself and realloc() crashes my program.
Constructor:
Stack::Stack()
{
st = (int*)malloc(sizeof(int));
sp = 0;
length = 1;
}
This is my add() function:
void Stack::add(int item)
{
if (sp == length)
Stack::resizeStack(&st, &length, 1);
st[sp++] = item;
}
Resize function (I use the variable a in order to be able to reuse it for pop) :
void Stack::resizeStack(int **st, int *length, bool a)
{
if (a == 1)
*length *= 2;
else
*length /= 2;
realloc(*st, sizeof(int) * (*length));
}
This is how I test my stack:
Stack* myStack = new Stack();
for (int i = 0; i < 10; i += 1) {
myStack->add(i);
cout << myStack->getStackSize() << '\n';
}
free(myStack);
I have noticed that the program crashes at the end of the for.
I would appreciate if someone explained what I am doing wrong.
All those people who say, malloc() and free() are a bad idea in C++ are 100% correct. Prefer new and delete over malloc() and free() and prefer standard library containers over your own homebrew stack implementation.
Anyway, the real issue here is, that realloc() might allocate a new memory block and free the old one. It returns a pointer to the new one.
The correct call is:
*st = realloc(*st, sizeof(int) * (*length));
Now *st will store the new pointer and everything is all right.
Consider to use the standard library, instead of implementing your own fundamental data structures. It has a well designed interface, and is very thoroughly tested.
You are lucky that you get a crash. This is undefined behavior.
Let's see what Bjarne Stroustrup says about this from here:
No, in the sense that you cannot allocate an object with malloc() and
free it using delete. Nor can you allocate with new and delete with
free() or use realloc() on an array allocated by new.
The C++ operators new and delete guarantee proper construction and
destruction; where constructors or destructors need to be invoked,
they are. The C-style functions malloc(), calloc(), free(), and
realloc() doesn't ensure that. Furthermore, there is no guarantee that
the mechanism used by new and delete to acquire and release raw memory
is compatible with malloc() and free(). If mixing styles works on your
system, you were simply "lucky" - for now.
C++ FAQ has also special entry for this:
https://isocpp.org/wiki/faq/freestore-mgmt#realloc-and-renew
Crashing at the end is most likely because you're mixing new with free. This is undefined behaviour. It may work on some systems, but is never a good idea. You should pair new with delete. Calls to malloc are paired with free, but these are more for C code. C++ code usually uses new and delete.
Of course you can eliminate the new by making myStack a local variable:
Stack myStack;
You would also need to adjust member access to use . instead of ->. There would be no need to delete myStack, since local variables would be automatically cleaned up once the function exits, including in the case of exceptions.
Also noticed the return value of realloc is ignored. If the current memory block can't be extended by realloc, it must allocate a new memory block and copy the old data over to it. A new pointer is returned in this case, so st must be updated.
*st = realloc(*st, sizeof(int) * (*length));
But again, using malloc, realloc, and free is a bit odd in C++ code.
You can use new[] and delete[] if you're forced to use manual memory management of arrays (such as for learning), or you can use the vector or stack classes for more serious code.
Use std::vector and it will automatically take care of all the memory management for you. In fact, you pretty much just don't need a Stack class in the face of std::stack but that's another matter.
Furthermore for the test do not allocate the Stack dynamically in a super pointless way, just make a local Stack.
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.
void aFunction_2()
{
char* c = new char[10];
c = "abcefgh";
}
Questions:
Will the: c = "abdefgh" be stored in the new char[10]?
If the c = "abcdefgh" is another memory area should I dealloc it?
If I wanted to save info into the char[10] would I use a function like strcpy to put the info into the char[10]?
Yes that is a memory leak.
Yes, you would use strcpy to put a string into an allocated char array.
Since this is C++ code you would do neither one though. You would use std::string.
void aFunction_2()
{
char* c = new char[10]; //OK
c = "abcefgh"; //Error, use strcpy or preferably use std::string
}
1- Will the: c = "abdefgh" be
allocated inner the new char[10]?
no, you are changing the pointer from previously pointing to a memory location of 10 bytes to point to the new constant string causing a memory leak of ten bytes.
2- If the c = "abcdefgh" is another
memory area should I dealloc it?
no, it hasn't been allocated on heap, its in read-only memory
3- If I wanted to save info inner the
char[10] I would use a function like
strcpy to put the info inner the
char[10]?
not sure what you mean with 'inner' here. when you allocate using new the memory is allocated in the heap and in normal circumstances can be accessed from any part of your program if you provide the pointer to the memory block.
Your answer already has been answered multiple times, but I think all answers are missing one important bit (that you did not ask for excplicitly):
While you allocated memory for ten characters and then overwrote the only pointer you have referencing this area of memory, you are created a memory leak that you can not fix anymore. To do it right, you would std::strcpy() the memory from the pre-allocated, pre-initialized constant part of the memory where the content of your string-literal has been stored into your dynamically allocated 10 characters.
And here comes the important part:
When you are done with dealing with these 10 characters, you deallocate them using delete[]. The [] are important here. Everything that you allocate using new x[] has to be deallocated with delete[]. Neither the compiler nor the runtime warn you when use a normal delete instead, so it's important to memorize this rule.
No, that is only pointer reassignment;
No, deleteing something that didn't come from new will often crash; and
Yes, strcpy will do the job… but it's not usually used in C++.
Since nobody has answered with code, std::uninitialized_copy_n (or just std::copy_n, it really doesn't make a difference here) is more C++ than strcpy:
#include <memory>
static char const abcs[] = "abcdefgh"; // define string (static in local scope)
char *c = new char[10]; // allocate
std::copy_n( abcs, sizeof abcs, c ); // initialize (no need for strlen)
// when you're done with c:
delete[] c; // don't forget []
Of course, std::string is what you should use instead:
#include <string>
std::string c( "abcdefgh" ); // does allocate and copy for you
// no need for delete when finished, that is automatic too!
No (pointer reassignment)
No
Yes, you can use strcpy(), see for instance:
following a discussion in a software meeting I've set out to find out if deleting a dynamically allocated, primitives array with plain delete will cause a memory leak.
I have written this tiny program and compiled it with visual studio 2008 running on windows XP:
#include "stdafx.h"
#include "Windows.h"
const unsigned long BLOCK_SIZE = 1024*100000;
int _tmain()
{
for (unsigned int i =0; i < 1024*1000; i++)
{
int* p = new int[1024*100000];
for (int j =0;j<BLOCK_SIZE;j++) p[j]= j % 2;
Sleep(1000);
delete p;
}
}
I than monitored the memory consumption of my application using task manager, surprisingly the memory was allocated and freed correctly, allocated memory did not steadily increase as was expected
I've modified my test program to allocate a non primitive type array :
#include "stdafx.h"
#include "Windows.h"
struct aStruct
{
aStruct() : i(1), j(0) {}
int i;
char j;
} NonePrimitive;
const unsigned long BLOCK_SIZE = 1024*100000;
int _tmain()
{
for (unsigned int i =0; i < 1024*100000; i++)
{
aStruct* p = new aStruct[1024*100000];
Sleep(1000);
delete p;
}
}
after running for for 10 minutes there was no meaningful increase in memory
I compiled the project with warning level 4 and got no warnings.
is it possible that the visual studio run time keep track of the allocated objects types so there is no different between delete and delete[] in that environment ?
delete p, where p is an array is called undefined behaviour.
Specifically, when you allocate an array of raw data types (ints), the compiler doesnt have a lot of work to do, so it turns it into a simple malloc(), so delete p will probably work.
delete p is going to fail, typically, when:
p was a complex data type - delete p; won't know to call individual destructors.
a "user" overloads operator new[] and delete[] to use a different heap to the regular heap.
the debug runtime overloads operator new[] and delete[] to add extra tracking information for the array.
the compiler decides it needs to store extra RTTI information along with the object, which delete p; won't understand, but delete []p; will.
No, it's undefined behavior. Don't do it - use delete[].
In VC++ 7 to 9 it happens to work when the type in question has trivial destructor, but it might stop working on newer versions - usual stuff with undefined behavior. Don't do it anyway.
It's called undefined behaviour; it might work, but you don't know why, so you shouldn't stick with it.
I don't think Visual Studio keeps track of how you allocated the objects, as arrays or plain objects, and magically adds [] to your delete. It probably compiles delete p; to the same code as if you allocated with p = new int, and, as I said, for some reason it works. But you don't know why.
One answer is that yes, it can cause memory leaks, because it doesn't call the destructor for every item in the array. That means that any additional memory owned by items in the array will leak.
The more standards-compliant answer is that it's undefined behaviour. The compiler, for example, has every right to use different memory pools for arrays than for non-array items. Doing the new one way but the delete the other could cause heap corruption.
Your compiler may make guarantees that the standard doesn't, but the first issue remains. For POD items that don't own additional memory (or resources like file handles) you might be OK.
Even if it's safe for your compiler and data items, don't do it anyway - it's also misleading to anyone trying to read your code.
no, you should use delete[] when dealing with arrays
Just using delete won't call the destructors of the objects in the array. While it will possibly work as intended it is undefined as there are some differences in exactly how they work. So you shouldn't use it, even for built in types.
The reason seems not to leak memory is because delete is typically based on free, which already knows how much memory it needs to free. However, the c++ part is unlikely to be cleaned up correctly. I bet that only the destructor of the first object is called.
Using delete with [] tells the compiler to call the destructor on every item of the array.
Not using delete [] can cause memory leaks if used on an array of objects that use dynamic memory allocations like follows:
class AClass
{
public:
AClass()
{
aString = new char[100];
}
~AClass()
{
delete [] aString;
}
private:
const char *aString;
};
int main()
{
AClass * p = new AClass[1000];
delete p; // wrong
return 0;
}