HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Allocating memory for a matrix with a single malloc

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withsingleformemorymallocmatrixallocating

Problem

For an interview, I was asked to write code allocate memory for a rows*cols matrix, using a single malloc(). I want your comments about this code that I wrote:

/*
Allots (in effect) space for a matrix of size rows*cols using a single malloc. 
The whole space allotted consists of an array of size 'rows' of float ptrs,
followed by a float array of size  'rows' * 'cols'. 
The float ptrs 1,2..,  are assigned to row no. 1, 2,..  in the matrix that follows.
*/

float** allotMatrix(const size_t &rows, const size_t &cols)
{
    // Compute size of allotment = rows * cols floats + rows float ptrs
    size_t ptrsize = rows * sizeof(float*);
    size_t datasize = rows * cols * sizeof(float);
    size_t matsize =  ptrsize + datasize;

    // Get if possible a memory allotment  of this size. We use char* for convenience
    char* cmatrix = (char*) malloc(matsize);
    if (cmatrix == NULL)
    {
        fprintf(stderr, "Unable to allot memory");
        exit(1);
    }

    memset((void*) cmatrix, 0, matsize);

    // Assign ptrs to data
    float** ptrstart = (float**) cmatrix;
    float* datastart = (float*) (cmatrix + ptrsize);
    for (size_t i = 0; i != rows; ++i)
    {

        *ptrstart =  datastart;
        // Move to next ptr
        ++ptrstart;
        // .. and move to the next data row
        datastart += cols;
    }

    return (float**) cmatrix;
}

Solution

I would use calloc instead of malloc since you're anyway clearing the matrix after allocation.

void* cmatrix = calloc(1, matsize);
...
//memset((void*) cmatrix, 0, matsize);  this is not needed anymore because of 'calloc'


Also I do not think there is any point in using char here because. Looks like you're using char only because it allows you to increment pointers by bytes. I think using float** here would be even more convinient:

float** cmatrix = (float**) calloc(1, matsize);
if (cmatrix == NULL) { ... }
float* datastart = (float*) (cmatrix + rows); // you don't need char pointers here
for (...) { ... }

Code Snippets

void* cmatrix = calloc(1, matsize);
...
//memset((void*) cmatrix, 0, matsize);  this is not needed anymore because of 'calloc'
float** cmatrix = (float**) calloc(1, matsize);
if (cmatrix == NULL) { ... }
float* datastart = (float*) (cmatrix + rows); // you don't need char pointers here
for (...) { ... }

Context

StackExchange Code Review Q#1479, answer score: 5

Revisions (0)

No revisions yet.