For Code
int main() {
int test;
cin >> test;
while (test--) {
int arr[100];
arr[0] = 0;
}
return 0;
}
Suppose test = 3.
For the first test case, array is allocated at address 1000. For the second test case array allocated at 2000 and so on. So, if we have lots of test cases, can our previous allocated memory address be used for further allocation? Does it automatically "free()" our previous allocated memory or it just cannot be used further?
arr is an automatic variable with block scope. You can use it, take its address etc, only inside the block it is declared. That's what the language specification says. It "comes to life" when we enter the block, and dies when we exit leave block. And that happens every time execution passes through that block; every iteration of the loop.
Compilers take advantage of this requirement by the C++ language. Instead of increasing the memory usage of your program, it's very likely the compiler will re-use the same storage for every iteration of the loop.
If you allocate an array with the following code, you will allocate memory in stack. As soon as your code reaches end of the scope ( which is curly bracket ) stack pops out and you are no longer able to access that portion of memory. Yes it is freed automatically.
//anything here
{
int arr[100];
}
// can not access arr
If you want to access after the curly bracket ( I actually mean changing the scope ), you need to allocate memory in heap for that array. You can do it either by using new keyword or malloc() . But this time you need to free the memory (no auto-free anymore) by using delete and free(), consecutively.
//anything here
int* arr
{
arr = new int[100];
}
// can access arr
delete [] arr
Please keep in mind that allocating memory in stack is faster but the size of it
is limited.
The compiler will allocate and deallocate memory in the stack for you if you call int arr[100] (i.e. it will be deallocated after exiting the scope that the variable is in). If you want to manage memory yourself, you need to use int *p = new int[100] and the memory will be allocated in the heap which you can manage yourself. The memory will stay allocated until you call delete[]. If you don't use delete[] after you don't need the memory anymore, you'll get memory leak.
Related
int a[10];
The above code will create a array of four int variable sizes & thus the programme will be able to store only 4 integers.
Now consider the following commands
int *a,*b,*c,*d;
a= (int *)malloc(sizeof(int));
b= (int *)malloc(sizeof(int));
c= (int *)malloc(sizeof(int));
d= (int *)malloc(sizeof(int));
The above part of code will create four int type pointer & will allocate them memory of int size.
I learnt that dynamic memory allocation allocates memory at rum time.
I want to know that irrespective of using array or malloc(dynamic memory allocation), the user will be getting only four int sized space to store.If we rule out that it is a pointer variable with int size memory, then what will be the use of dynamic memory allocation.In both cases , the user will get only four int spaces & to get more he will need to access the source code.So why do we use malloc or dynamic memory allocation ?
Consider
int a,*b;
cin >> a;
b= (int *)malloc(a*sizeof(int));
The user types a number a and gets a ints. The number a is not known to either to programmer or the compiler here.
As pointed out in the comments, this is still bad style in C++, use std::vector if possible. Even new is still better than malloc. But i hope the (bad) example helps to clarify the basic idea behind dynamic memory allocation.
You're right that it's all just memory. But there is a difference in usage.
In the general case, you don't necessarily know ahead of time the amount of memory you will need and then time when such memory can be safely released. malloc and its friends are written so that they can keep track of memory used this way.
But in many special cases, you happen to know ahead of time how much memory you will need and when you will stop needing it. For example, you know you need a single integer to act as a loop counter when running a simple loop and you'll be done with it once the loop has finished executing. While malloc and its friends can still work for you here, local variables are simpler, less error prone and will likely be more efficient.
int a[10];
The above line of code will allocate an array of 10 int's of automatic storage duration, if it was within a local scope.
int *a,*b,*c,*d;
The above, however, will allocate 4 pointers to int also of automatic storage duration, likewise if it was within a local scope.
a= (int *)malloc(sizeof(int));
b= (int *)malloc(sizeof(int));
c= (int *)malloc(sizeof(int));
d= (int *)malloc(sizeof(int));
And finally, the above will allocate int variable per each pointer dynamically. So, every pointer of the above will be pointing to a single int variable.
Do note that dynamically allocated memory can be freed and resized at runtime unlike static memory allocation. Memory of automatic storage duration are freed when run out of scope, but cannot be resized.
If you program in C, casting the result of malloc is unnecessary.
I suggest you to read this: Do I cast the result of malloc?
Then what your doing in your code with the 4 pointers is unnecessary; in fact you can just allocate an array of 4 int with one malloc:
int *a;
a = malloc(4 * sizeof(int));
Suppose I have the following snippet.
int main()
{
int num;
int* cost;
while(cin >> num)
{
int sum = 0;
if (num == 0)
break;
// Dynamically allocate the array and set to all zeros
cost = new int [num];
memset(cost, 0, num);
for (int i = 0; i < num; i++)
{
cin >> cost[i];
sum += cost[i];
}
cout << sum/num;
}
` `delete[] cost;
return 0;
}
Although I can move the delete statement inside the while loop
for my code, for understanding purposes, I want to know what happens with the code as it's written. Does C++ allocate different memory spaces each time I use operator new?
Does operator delete only delete the last allocated cost array?
Does C++ allocate different memory spaces each time I use operator new?
Yes.
Does operator delete only delete the last allocated cost array?
Yes.
You've lost the only pointers to the others, so they are irrevocably leaked. To avoid this problem, don't juggle pointers, but use RAII to manage dynamic resources automatically. std::vector would be perfect here (if you actually needed an array at all; your example could just keep reading and re-using a single int).
I strongly advise you not to use "C idioms" in a C++ program. Let the std library work for you: that's why it's there. If you want "an array (vector) of n integers," then that's what std::vector is all about, and it "comes with batteries included." You don't have to monkey-around with things such as "setting a maximum size" or "setting it to zero." You simply work with "this thing," whose inner workings you do not [have to ...] care about, knowing that it has already been thoroughly designed and tested.
Furthermore, when you do this, you're working within C++'s existing framework for memory-management. In particular, you're not doing anything "out-of-band" within your own application "that the standard library doesn't know about, and which might (!!) it up."
C++ gives you a very comprehensive library of fast, efficient, robust, well-tested functionality. Leverage it.
There is no cost array in your code. In your code cost is a pointer, not an array.
The actual arrays in your code are created by repetitive new int [num] calls. Each call to new creates a new, independent, nameless array object that lives somewhere in dynamic memory. The new array, once created by new[], is accessible through cost pointer. Since the array is nameless, that cost pointer is the only link you have that leads to that nameless array created by new[]. You have no other means to access that nameless array.
And every time you do that cost = new int [num] in your cycle, you are creating a completely new, different array, breaking the link from cost to the previous array and making cost to point to the new one.
Since cost was your only link to the old array, that old array becomes inaccessible. Access to that old array is lost forever. It is becomes a memory leak.
As you correctly stated it yourself, your delete[] expression only deallocates the last array - the one cost ends up pointing to in the end. Of course, this is only true if your code ever executes the cost = new int [num] line. Note that your cycle might terminate without doing a single allocation, in which case you will apply delete[] to an uninitialized (garbage) pointer.
Yes. So you get a memory leak for each iteration of the loop except the last one.
When you use new, you allocate a new chunk of memory. Assigning the result of the new to a pointer just changes what this pointer points at. It doesn't automatically release the memory this pointer was referencing before (if there was any).
First off this line is wrong:
memset(cost, 0, num);
It assumes an int is only one char long. More typically it's four. You should use something like this if you want to use memset to initialise the array:
memset(cost, 0, num*sizeof(*cost));
Or better yet dump the memset and use this when you allocate the memory:
cost = new int[num]();
As others have pointed out the delete is incorrectly placed and will leak all memory allocated by its corresponding new except for the last. Move it into the loop.
Every time you allocate new memory for the array, the memory that has been previously allocated is leaked. As a rule of thumb you need to free memory as many times as you have allocated.
The following code gives me a segmentation fault:
bool primeNums[100000000]; // index corresponds to number, t = prime, f = not prime
for (int i = 0; i < 100000000; ++i)
{
primeNums[i] = false;
}
However, if I change the array declaration to be dynamic:
bool *primeNums = new bool[100000000];
I don't get a seg-fault. I have a general idea of why this is: in the first example, the memory's being put on the stack while in the dynamic case it's being put on the heap.
Could you explain this in more detail?
bool primeNums[100000000];
used out all your stack space, therefore, you will get segmentation fault since there is not enough stack space to allocate a static array with huge size.
dynamic array is allocated on the heap, therefore, not that easy to get segmentation fault. Dynamic arrays are created using new in C++, it will call operator new to allocate memory then call constructor to initialize the allocated memory.
More information about how operator new works is quoted from the standard below [new.delete.single]:
Required behavior:
Return a nonnull pointer to suitably aligned storage (3.7.3), or else throw a bad_alloc exception. This requirement is binding on a replacement version of this function.
Default behavior:
— Executes a loop: Within the loop, the function first attempts to allocate the requested storage. Whether the attempt involves a call to the Standard C library function malloc is unspecified.
— Returns a pointer to the allocated storage if the attempt is successful. Otherwise, if the last argument to set_new_handler() was a null pointer, throw bad_alloc.
— Otherwise, the function calls the current new_handler (18.4.2.2). If the called function returns, the loop repeats.
— The loop terminates when an attempt to allocate the requested storage is successful or when a called new_handler function does not return.
So using dynamic array with new, when there is not enough space, it will throw bad_alloc by default, in this case, you will see an exception not a segmentation fault, when your array size is huge, it is better to use dynamic array or standard containers such as vectors.
bool primeNums[100000000];
This declaration allocates memory in the stack space. The stack space is a memory block allocated when your application is launched. It is usually in the range of a few kilobyes or megabytes (it depends on the language implementation, compiler, os, and other factors).
This space is used to store local and static variables so you have to be gentle and don't overuse it. Because this is a stack, all allocations are continuos (no empty space between allocations).
bool *primeNums = new bool[100000000];
In this case the memory is allocated is the heap. This is space free where large new chucks of memory can be allocated.
Some compilers or operating systems limit the size of the stack. On windows the default is 1 MB but it can be changed.
in the first case you allocate memory on stack:
bool primeNums[100000000]; // put 100000000 bools on stack
for (int i = 0; i < 100000000; ++i)
{
primeNums[i] = false;
}
however this is allocation on heap:
bool *primeNums = new bool[100000000]; // put 100000000 bools in the heap
and since stack is (very) limited this is the reason for segfault
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.
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.