4
\$\begingroup\$

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;
}
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Mar 26, 2011 at 22:51
\$\endgroup\$

2 Answers 2

5
\$\begingroup\$

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 (...) { ... }
answered Mar 26, 2011 at 23:39
\$\endgroup\$
5
  • \$\begingroup\$ arithmetic such as (cmatrix+ptrsize) can't be done with void*. \$\endgroup\$ Commented Mar 26, 2011 at 23:48
  • 2
    \$\begingroup\$ There's no guarantee in the C standard that the zeroing that calloc() does creates floating point zeroes. That said, with the IEEE 754 standard, you do get zeroes, and that covers an awful lot of machines these days. \$\endgroup\$ Commented Mar 27, 2011 at 2:49
  • \$\begingroup\$ @Jonathan, I wasn't talking about floating point zeros, OP originally was zeroing the memory with memset and I believe it will behave in the same way as calloc. And I don't know how both these approaches work with floating point zeroz, I just say that one can be replaced with other. \$\endgroup\$ Commented Mar 27, 2011 at 8:16
  • \$\begingroup\$ @Ganesh, got your point, updated my answer \$\endgroup\$ Commented Mar 27, 2011 at 8:23
  • 1
    \$\begingroup\$ not good practice to cast the return value of calloc/malloc, it returns a void* so there is no need to cast \$\endgroup\$ Commented Jan 26, 2015 at 7:01
1
\$\begingroup\$

I would not pass rows and cols by reference in this case, most cases it will have the same size as a pointer, no gain using it as reference.

answered Mar 28, 2011 at 11:44
\$\endgroup\$
2
  • \$\begingroup\$ does C even have references? I thought that was limited to C++. Was it added to the latest standard? \$\endgroup\$ Commented Mar 29, 2011 at 21:44
  • \$\begingroup\$ As far I know no references for C, only pointers. \$\endgroup\$ Commented Mar 30, 2011 at 14:13

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.