LM_O
LM_O

Reputation: 131

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 !

Upvotes: 0

Views: 1363

Answers (3)

user4272649
user4272649

Reputation:

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.

Upvotes: 1

cdhowie
cdhowie

Reputation: 168988

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.

Upvotes: 1

Tommy
Tommy

Reputation: 100622

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.

Upvotes: 1

Related Questions