1

I am using these lines to create variable size matrices:

Temp_Mat_0 = (double  **)malloc((M)*sizeof(double  ));
for (i=0;i<M;i++)
    Temp_Mat_0[i] = (double  *)malloc((N)*sizeof(double  ));

They are working fine but I keep using them repeatedly in my code. I need to convert them to a function where I pass the pointer and the size. I was not able to do it due to pointers mess.

matrixAllocate(Matrix Pointer,rows,colms)

Can you help!

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Karam Abo Ghalieh
  • 428
  • 1
  • 5
  • 19

2 Answers2

2

they are working fine

They do not seem really fine. Code should be changed to :

Temp_Mat_0 = malloc((M)*sizeof(double*));  //double* instead of double
if (Temp_Mat_0 == NULL)
    return;
for (i = 0; i < M; i++){
    Temp_Mat_0[i] = malloc((N)*sizeof(double));
    if (Temp_Mat_0[i] == NULL){
        free(Temp_Mat_0);
        return;
    }
}

Then, you can use a function like this :

double ** matrix_pointer = matrixAllocate(rows,colms);

where function matrixAllocate returns the pointer it allocated. For example :

matrixAllocate(rows,colms){
    Temp_Mat_0 = malloc((rows)*sizeof(double*));  
    if (Temp_Mat_0 == NULL)
        return NULL;
    for (i = 0; i < rows; i++){
        Temp_Mat_0[i] = malloc((colms)*sizeof(double));
        if (Temp_Mat_0[i] == NULL){
           free(Temp_Mat_0);
           return NULL;
        }
    }
    return Temp_Mat_0;
}

and call it like :

double **matrix pointer;
matrix pointer = matrixAllocate(rows, colms);

Don't forget to free the malloced memory afterwards.

for (i = 0; i < M; i++){
    free(Temp_Mat_0[i]);
}
free(Temp_Mat_0);

Note that you should not cast the result of malloc, and you should also check if malloc was successful.

Community
  • 1
  • 1
Marievi
  • 4,951
  • 1
  • 16
  • 33
  • 1
    @LPs If malloc fails there's no hope of recovering the program as it is out of heap memory... at that point it doesn't matter much what the program does, it has to get shut down. – Lundin May 09 '17 at 06:42
  • @Lundin It really depends on the whole code. Heap is not corrupted so the situation can be resolved somehow. – LPs May 09 '17 at 06:50
  • @LPs No it doesn't... your program can't attach more RAM hardware to the computer. To keep executing after a failed heap allocation is highly questionable practice. – Lundin May 09 '17 at 06:53
  • @Lundin Not this case obviously, but I can easily imagine an application that try to allocate and on fail sleeps in a wait queue until other tasks/threads finish their job and release heap memory... Just to say: what you wrote is correct but "application dependent" – LPs May 09 '17 at 06:56
  • I need to define Temp_Mat_0 as double** in your code, right? – Karam Abo Ghalieh May 09 '17 at 19:28
2

I think you'd be better off with a very simple scheme that allocates your matrix as a single contiguous block.

double **matrix_alloc(int rows, int cols)
{
    /* Allocate array of row pointers */
    double ** m = malloc(rows * sizeof(double*));
    if (!m) return NULL;

    /* Allocate block for data */
    m[0] = malloc(rows * cols * sizeof(double));
    if (!m[0]) {
        free(m);
        return NULL;
    }

    /* Assign row pointers */
    for(int r = 1; r < rows; r++) {
        m[r] = m[r-1]+cols;
    }

    return m; 
}

This has the added bonus that when you free the matrix you don't need to remember how big it was:

matrix_free( double** m )
{
    if (m) free(m[0]);
    free(m);
}

As an extension to this, you might declare a struct that also keeps track of the number of rows and columns it has. e.g.

struct matrix {
    int rows, cols;
    double **m;
};

That makes your matrix functions look a little nicer (i.e. you can pass around struct matrix* instead of double**). It has the added bonus that the matrix dimension travels around with the associated data.

Using one contiguous block for your matrix data is generally preferable unless you have huge matrices. And it's very nice if your matrices are small, because you'll get the benefit of better memory locality in your CPU cache -- that means potential for faster code.

paddy
  • 60,864
  • 6
  • 61
  • 103
  • I have this error cannot convert from 'void *' to 'double **' for this line double ** m = malloc(rows * sizeof(double*)); is it related to windows or VS – Karam Abo Ghalieh May 09 '17 at 19:37
  • 1
    You're probably using a C++ compiler without realising. Just cast the return value as you did in your question. – paddy May 09 '17 at 20:25