How Dynamic memory allocation allocates memory during run time ? - c++

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));

Related

Can locally allocated memory be used for future uses?

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.

Memory deallocation of pointer variable in c++

If I take a block of memory by the following line .
int* a = new int[10];
Then for freeing the memory , the code would be
delete [] a;
But if I take a pointer of single memory segment like the following
int* a = new int;
And then insert a array of data like following .
for(int i=0;i<10;i++)
{
a[i]= i ;
}
So to free the first memory segment that pointer "a" is pointing, the code would be like following
delete a;
But Here I inserted 9 more data from the memory that pointer "a" is pointing .So I am using actually 10 memory segment here . how can I free all this 10 memory ? Please help me to get the answer .
how can I free all this 10 memory ?
You can't and you shouldn't because the moment you tried to "insert a array of data like following" you have entered Undefined Behavior land for writing to a location that you didn't allocate with new in the first place. You asked for a single int, you got a single int. Don't write past it.
You allocated only one int. Memory from a[1] to a[9] may be assigned to other objects and you may corrupt them.
P.S. Btw you can not free memory that you did not allocate in any case.
new int allocates space for one int value. You cannot legally pretend that it's an array of ten int values, and the compiler won't generate code to expand the allocated memory if you go out of bounds. The code you wrote produces undefined behavior. The fact that it compiled and ran doesn't change that; sooner or later it will cause problems.
To allocate an array that can hold 10 int values, use your first expression: new int[10]. That will allocate space for ten int values.
To allocate an array that can be expanded at will, use std::vector<int>.

What if I delete an array once in C++, but allocate it multiple times?

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.

Dynamic Allocation of memory c++ performance improvements

Good night
I'm learning C++ for scientific code development. Differently of my learning strategy used in python and MATLAB, I'm trying to learn C++ in old and deep way (using a book ref[1]). I'm struggling to understand pointers and dynamic memory allocation.
I came across this exercise and some doubts appeared. The exercise is a simple 2x2 matrix multiplication. The code:
#include<iostream>
//Perform C[2][2] = A[2][2]*B[2][2] Using dynamic memory allocation
int main(){
//declaring length of the matrices
int row,col;
row = 2;
col = 2;
//Allocating memory for matrice A [heap ?]
double** A, **B, **C;
A = new double* [row];
B = new double* [row];
C = new double* [row];
for (int i=0; i<row; ++i){
A[i] = new double [col];
B[i] = new double [col];
C[i] = new double [col];
}
//Performing calculation
for (int i=0; i<2; ++i){
for (int j=0; j<2; ++j){
A[i][j] += 10;
B[i][j] += 20;
C[i][j] += A[i][j]*B[i][j];
std::cout << C[i][j] << " ";
}
std::cout << std::endl;
}
//Deleting memory allocation [Is there an memory leak ? (No *=NULL)]
for (int i=0; i<2; ++i){
delete[] A[i];
delete[] B[i];
delete[] C[i];
}
delete[] A;
delete[] B;
delete[] C;
return 0;
}
My doubts are:
1 - I read about the memory division (global/stack/heap), where are they located in the hardware ? HD/RAM/CPU cache ?
2 - when I allocate an array:
int arrayS[2]; //Is this at the stack ?
int* arrayH; //Is this at the heap ?
arrayH = new int [2];
3 - In my resolution of the matrix problem. Is there a memory leak or garbage creation ? (note I didn't pointed the arrays to *=NULL to get rid of the address)
4 - Do you suggest any way to improve my code performance and efficiency ?
Thank you !
1) The global area, stack and heap are all located within your application's CPU address space. Which will mean they're in RAM, subject to virtual memory paging (in which case they may go and live on the HD for a while) and CPU caching (in which case they may go and live on the CPU for a while). But both of those things are transparent as far as the generated code is concerned.
2) yes, arrayS[2] will be on the stack (unless it's global, of course), and anything returned by new (or malloc, should you include some C code) is on the heap.
3) I can't see any leaks but if you're going to use row and col rather than repeating the 2 magic constant all over the place then do so uniformly and mark them as const so that you can't accidentally modify them.
4) in terms of cache efficiency, it may be better to do one allocation as new double[col * row] and then either to spread your pointers out throughout that block or to index as [i*col + j], assuming i indexes rows and all rows are col items long. new is otherwise permitted to spread your rows out wherever it likes across memory, which is more likely to lead to cache faults.
As to style? Well, you didn't ask, but I think cdhowie's comment is valid. Also Deduplicator's point should be read more deeply: the STL has a bunch of pieces to help make sure you don't leak memory — read up on unique_ptr and shared_ptr.
I read about the memory division (global/stack/heap), where are they located in the hardware ? HD/RAM/CPU cache ?
They can all be stored wherever your particular C++ program decides that they should be. Some local variables are likely to exist only in registers, if they have a short life span and never have a pointer taken to them.
Odds are that everything else will wind up somewhere in system RAM (which can be paged out to disk, if your process is unlucky). The difference is how they are used by the program, not where they happen to be. Where they are is an implementation detail that you don't really need to worry about.
when I allocate an array
Yes, your analysis of stack vs. heap there is correct. Your first one (int arrayS[2];) has the caveat that if you declare this variable as part of a class or struct, it could exist either place depending on how the class/struct gets created. (If the class/struct gets created on the heap then the array would be on the heap; if it gets created on the stack then on the stack.)
And of course if it's a global then it has global storage.
Do you suggest any way to improve my code performance and efficiency ?
Encapsulate the concept of a matrix inside of a class, and use std::vector instead of allocating your own arrays. The amount of indirection will be the same after compiler optimization, but you no longer have to concern yourself with managing the memory used by the arrays.
In c++ the object can be located stack and in heap.In your example int arrayS[2] is located in the stack of the funcion in which it was declared.If you want to create object in heap (a memory that is available to all the functions that exists in the program ) you must use the operator new.The pointer that keeps the address of the object allocated (in your case arrayH) is also push in the stack of the function in which it is declared
Actually memory of one process(program that is being executable) is dived in three parts:
Code Area (is the area in which the code of the program is located );
The stack area (is starts at the location where the Stack-Pointer points in memory.Stack pointer is a register that keeps every time the address of the current stack.In a program more that one stack at one time,this depends on the level of recursivity of your program)
The data area (is the global memory accessible from entire program.It is allocated in c++ only with new Operator or as global variable)
It exists also shared_memory which permits to the programmer to allocate memory available in more than one process.
**There is no memory leak in your code.But in c++ are implemented the concept of smart_pointer which is very similar with the garabage-colector from C# and Java **
Also the C++ is an OOP programming language so you definitely should write your code using classes ,inheritance,polimorfism etc.

Stack overflow when declare 2 array

When I run my program with 1 array, like this:
int a[430][430];
int i, j, i_r0, j_r0;
double c, param1, param2;
int w_far = 0,h_far = 0;
char* magic_num1 = "";
it's good!
But, when I write:
int a[430][430];
int i, j, i_r0, j_r0;
int nicky[430][430]; // Added line
double c, param1, param2;
int w_far = 0,h_far = 0;
char* magic_num1 = "";
the program not run with the error: "stack overflow"!
I don't know how to solve it!
You need to either increase the stack space (how that is done depends on your platform), or you need to allocate the array from the heap, or even better, use std::vector instead of an array.
You're trying to allocate ~1.48 MB of stuff on the stack1, on your system (and not only on it) that's too much.
In general, the stack is not made for keeping big objects, you should put them in the heap instead; use dynamic allocation with new or std::vector, or, even better suited in your case, boost::multi_array.
1. Assuming 32 bit ints.
A proper solution is to use heap, but also note that you'll likely find that changing to:
short a[430][430];
short nicky[430][430]; // Added line
fixes the overflow, depending on your platform. So if 'short', or 'unsigned short' is big enough, this might be an option.
In fact, even when using the heap, consider carefully the array type to reduce memory footprint for a large array.
Local variables are allocated to "stack", which is a storage space used to several purposes and limited to a certain size.
Usually you can declare variables up to several kilobytes, but when you want to use more memory, usually suggested to use "heap", which can be allocated by new operator or std::vector.
std::vector is an alternate for traditional arrays, and its data is safely stored in heap.
To avoid stack overflow, allocate the arrays in the heap.
If one uses C, then allocating an array of size n in the heap can be done by e.g.
int* A = (int*) malloc(n*sizeof(int));
But you must remeber to free that memory when no longer needed with
free(A);
to avoid memory leak.
Equivalently in C++:
int* A = new int[n];
and free with
delete [] A;
This site was helpful.