user1190832
user1190832

Reputation:

C matrix, allocating doesnt zero all elements?

I'm trying to write a little matrix program. Using doublke pointers doesnt work so I figure the easiest way is to have a struct that has the #rows and #columns and a 1d array as the matrix.

But there is some error in the initiation of the matrix as i get: weird values for the indices (0,0) and (0.1) instead of 0.

Something with this perhaps: matrix *mtrx = malloc(sizeof(matrix)); mtrx->m = malloc(r * c * sizeof(int));

matrix.c:

#include <stdio.h>
#include <stdlib.h>
#include "Matrix.h"

matrix *alloc_matrix(int r, int c)
{
 matrix *mtrx = malloc(sizeof(matrix));
 mtrx->m = malloc(r * c * sizeof(int));
 if (mtrx == NULL || m == NULL) {
   printf("Out of memory.");
   exit(1);
 }
 mtrx->rows = r;
 mtrx->columns = c;
 return mtrx;
}

void free_matrix(matrix *mtrx)
{
 free(mtrx->m);
 free(mtrx);
}

void set(matrix *mtrx, int r, int c, int v)
{
 (mtrx->m)[r * mtrx->columns + c] = v;
}

int get(matrix *mtrx, int r, int c)
{
 return (mtrx->m)[r * mtrx->columns + c];
}

void print_matrix(matrix *mtrx)
{
 int i,j;
 printf("\n");
 for(i=0; i<mtrx->rows; i++) {
   for(j=0; j<mtrx->columns; j++) {
     printf("%i ", get(mtrx,i,j));
   }
   printf("\n");
 }
}

matrix.h:

struct matrix_ {
 int rows;
 int columns;
 int *m;
};
typedef struct matrix_ matrix;

matrix *alloc_matrix(int r, int c);
void free_matrix(matrix *mtrx);
void set(matrix *mtrx, int r, int c, int v);
int get(matrix *mtrx, int r, int c);
void print_matrix(matrix *m);

main.c:

#include <stdio.h>
#include <stdlib.h>
#include "Matrix.h"

int main(void)
{
 matrix *m = alloc_matrix(3,4);
 print_matrix(m);
 printf("\nm[0][0] = %i", get(m,0,0));
 set(m,0,0,0);
 printf("\nm[0][0] = %i", (m->m)[0]);
  printf("\nm[0][0] = %i", (m->m)[12]);

 return 0;
}

output: all elements except (0,0) and (0,1) is 0.

Upvotes: 3

Views: 1857

Answers (6)

Stephen Canon
Stephen Canon

Reputation: 106187

malloc does not zero out allocated memory. If you want to fill the matrix with zeros on allocation, use calloc instead. In your case, replace:

mtrx->m = malloc(r * c * sizeof(int));

with

mtrx->m = calloc(r*c, sizeof(int));

Answering your follow-up question:

However is there any difference in efficiency between malloc+memset and calloc? or is calloc simplye malloc+memset?

Typically, for "small" allocations calloc is equivalent to malloc + memset. For "large" allocations (multiple pages, at least), your library may do something more clever relying on some amount of OS support. One approach would be for the OS to lazily zero fill the allocated pages as they are actually used, rather than zero filling all of them immediately upon allocation.

Upvotes: 1

ouah
ouah

Reputation: 145839

The object allocated by malloc has an unspecified value. If needed, you have to zero-ize the object yourself (for example using memset function) or call calloc instead of malloc.

Upvotes: 2

Cellfish
Cellfish

Reputation: 2192

That is correct. The C specification does not say arrays are initilized to anything. You just get a piece of memory that will have whatever values there where before.

You can easily initialize to sero though: memset(mtrx->m, 0, sizeof(int) * r * c);

Upvotes: 0

LihO
LihO

Reputation: 42083

Function malloc allocates a block of memory, returning a pointer to the beginning of the block. It doesn't set all its bits to zero.

Allocating a block of memory and initializing all its bits to zero - that's what calloc function is for.

Or you can explicitly set these bits to zero by using memset

Upvotes: 7

Yochai Timmer
Yochai Timmer

Reputation: 49251

malloc does not initiate with 0's (because of performance issues... it's not always what you want)...

use calloc() instead.

Upvotes: 1

BitBank
BitBank

Reputation: 8715

malloc() is not guaranteed to zero the memory. Use calloc() to allocate memory with zeros.

Upvotes: 1

Related Questions