malloc causing a SIGSEGV:Segmentation fault - c

typedef struct Matrix
{
double * matrix;
int sizex;
int sizey;
}Matrix;
int nn = 257;
Matrix * g = (Matrix *)malloc(sizeof(Matrix *));
g->matrix = malloc(sizeof(double) * nn * nn);
g->sizex = nn;
g->sizey = nn;
This code give an error when it gets to g->matrix = malloc(sizeof(double) * nn * nn);
anyone see a problem with it ?
edit: found problem to be accessing unallocated memory in a place before the allocation shown, it was causing a SIGSEGV:Segmentation fault.

You need to pass malloc the sizeof the Matrix not sizeof pointer to the Matrix.
Change
Matrix * g = (Matrix *)malloc(sizeof(Matrix *));
^^
to
Matrix * g = (Matrix *)malloc(sizeof(Matrix));
Also you must always check the return value of malloc and make sure allocation succeed before you go and use the allocated memory.

I'm guessing you're using some ancient 16-bit compiler, probably Turbo C. Junk it and get gcc, either djgpp if you want to build DOS programs or mingw or cygwin if you want to build Windows programs.
Assuming I'm right, 257*257 overflows the maximum addressable size, 65536, not to mention what happens when you multiply it by 8.
Edit: OP changed the question after I wrote this so it may be completely off. If so I'll delete it.

Matrix * g = (Matrix *)malloc(sizeof(Matrix *));
should be
Matrix * g = (Matrix *)malloc(sizeof(Matrix));
You're only allocating the size of a pointer to Matrix, rather than a Matrix itself.

You do not allocate memory for a Matrix object, you are allocating for a pointer.
Change your first malloc call to do this:
Matrix * g = malloc(sizeof(*g));
I prefer this style as you do not need explicit pointer cast from void * in C, and you are allowed to do sizeof on the variable's underlying type. This could save you headaches just in case you change the type of g (or for future code).
Similarly for style:
g->matrix = malloc(sizeof(double) * nn * nn);
should be:
g->matrix = malloc(sizeof(*(g->matrix)) * nn * nn);

Parameter of your sizeof should not be a pointer.

Matrix * g = (Matrix *)malloc(sizeof(Matrix *));
This reserves enough heap space for a pointer to a Matrix, but you want enough heap space for the Matrix itself. Try:
Matrix* g = (Matrix*)malloc(sizeof(Matrix));
For a complete, working program:
#include <stdlib.h>
#include <stdio.h>
typedef struct Matrix {
double * matrix;
int sizex;
int sizey;
} Matrix;
int main()
{
int nn = 257;
Matrix * g = (Matrix *)malloc(sizeof(Matrix));
if (g == NULL)
{
printf("g = malloc() failed\n");
return 1;
}
g->matrix = malloc(sizeof(double) * nn * nn);
g->sizex = nn;
g->sizey = nn;
printf("g %p, g->matrix %p, g->sizex %d, g->sizey %d\n",
g, g->matrix, g->sizex, g->sizey);
return 0;
}
Output on my Linux box:
g 0x8822008, g->matrix 0xf6ea6008, g->sizex 257, g->sizey 257

I'll just add the direction of not casting malloc's return. It is unnecessary, pollutant, and might lead to unwanted behavior (as described here: http://c-faq.com/malloc/mallocnocast.html

Related

How to allocate memory equal in size to a variable read from an input file?

I'm building a code to simulate the response of some dynamical systems for my PhD. Basically what I'm trying to do is:
Ask the user for the name of a input file that contains all parameters for the simulation;
Read the input file and assign each parameter to a specific variable in my program.
Do the calculations.
I'm having problems on step 2, as one of the values in the input file is the dimension dim of an dinamically allocated array *x.
Here is a working example of the code:
#include <stdio.h>
#include <stdlib.h>
void read_file(char *name, int *dim, double **x) {
// Open input file
FILE *input = fopen(name, "r");
if (input == NULL) {
// Return error
perror(name);
return;
}
// Read and assign system constants
fscanf(input, "%i", dim);
printf("dim = %i\n", *dim);
// Allocate memory for x[dim]
*x = malloc((*dim) * sizeof(*x));
double y[(*dim)];
printf("size of (*x) = %llu\n", sizeof(*x));
printf("size of y = %llu\n", sizeof(y));
// Security check for pointers
if(*x == NULL) {
free(*x);
printf("Memory allocation for *x did not complete successfully\n");
return;
}
// assign values to x[dim] vector
for (int i = 0; i < *dim; i++) {
fscanf(input, "%lf", &(*x)[i]);
printf("(*x)[%i] = %lf\n", i, (*x)[i]);
}
// Close input file
fclose(input);
}
char *get_input_filename(void) {
char *filename = malloc(200 * sizeof(*filename));
printf("Enter Input Filename: ");
scanf("%s", filename);
return filename;
}
int main (void) {
int DIM;
double *x = NULL;
char *input_filename = get_input_filename();
read_file(input_filename, &DIM, &x);
printf("size of (*x) = %llu\n", sizeof(*x));
for (int i = 0; i < DIM; i++) {
printf("(*x)[%i] = %lf\n", i, x[i]);
}
free(x); free(input_filename);
}
And here is the content of the input file in.txt for this example:
5
0.0 0.1 0.2 1.4 2.6
When I call *x = malloc((*dim) * sizeof(*x)); I expected to find the dimension of the system to be 5 * 8bytes, as the value for *dim is assigned in the previous line, however only 8 bytes are allocated. Then, I declared the y[(*dim)] variable to check if the sizeof a VLA would behave in the same way as the sizeof *x, just to compare. The sizeof(y) was what I expected, but the sizeof(*x) wasn't, as shown in the output:
Enter Input Filename: in.txt
dim = 5
size of (*x) = 8
size of y = 40
(*x)[0] = 0.000000
(*x)[1] = 0.100000
(*x)[2] = 0.200000
(*x)[3] = 1.400000
(*x)[4] = 2.600000
size of (*x) = 8
(*x)[0] = 0.000000
(*x)[1] = 0.100000
(*x)[2] = 0.200000
(*x)[3] = 1.400000
(*x)[4] = 2.600000
I understand that it cannot allocate memory if the value of *dim is unknown, but a value is assigned in the previous line.
Also, I even don't know how the program assigned values to (*x) successfully as it don't have the necessary allocation of bytes to do it.
What am I missing here? How can I allocate the memory correctly?
Thanks in advance
Both dim and x are output arguments; pointers that refer to locations where you're to store your results of this function (a size and a memory allocation sequence of double values).
This is where things are going off the rails:
*x = malloc((*dim) * sizeof(*x));
The left side is ok. And so is most of the right side. But if you're ever allocating to a pointer based on the size of the dereferenced data a pointer points to, you need to do so using just that: the size of the thing the pointer points to. x is a pointer-to-pointer, *x is a pointer, and the latter is the 'thing' we're allocating memory for, the address of which will be stored at *x.
Therefore, that should be:
*x = malloc((*dim) * sizeof **x);
Note: when I'm using variables as the operator argument for sizeof I personally strive not to use parens. It ensures I'm actually using a variable id rather than a type id, since the latter isn't allowed without parens. use what you favor at your discretion/whim.
More fundamental, however, your familiarity and understanding of sizeof is wrong and/or misled. You cannot acquire the size of dynamic-allocated memory region using sizeof. Using the sizeof operator on a pointer variable will give you exactly what you asked for: the size of the pointer variable (e.g. the size of a pointer). It is your responsibility to maintain and track magnitude of dynamic allocations (which, btw, your code does, using dim).

Generic bidimensional array

I want to create a bidimensional array like so:
void **mdeclaraMatrice(int nrLini,int nrColoane, int sizeOfElement)
{
int i;
void **m = malloc(nrLini * 4);
if(m==NULL)
return NULL;
for(i=0; i<nrLini; i++)
{
*(m + (i*4)) = malloc(nrColoane * sizeOfElement);
if(*(m + (i*4)) == NULL)
return NULL;
}
return m;
}
I whant to use it like this:
int **m = (int **)mdeclaraMatrice(n,m,sizeof(int));
but it doesn't work. What do I do wrong?
You should use m[i] instead of *(m+i*4) and let the compiler do the arithmetic.
In addition, you should deallocate the already-allocated memory in case of a failure.
Try this instead:
void **mdeclaraMatrice(int nrLini, int nrColoane, int sizeOfElement)
{
int i;
void **m = malloc(nrLini * sizeof(void*));
if (m == NULL)
return NULL;
for (i=0; i<nrLini; i++)
{
m[i] = malloc(nrColoane * sizeOfElement);
if (m[i] == NULL)
{
while (i-- > 0)
free(m[i]);
free(m);
return NULL;
}
}
return m;
}
[not an answer to the question, but to the indented usage of the proper answer as given by others]
To access the void pointer array as an array of int, doing this
int **m = (int **)mdeclaraMatrice(n,m,sizeof(int));
is not correct, as per the C-Standard only void* converts to any other pointer properly, void** doesn't necessarily. So it shall correctly be
void ** ppv = mdeclaraMatrice(n,m,sizeof(int));
int * pi = *ppv; /* Please note, there is NO casting necessary here! */
Then access the members like so:
pi[0] = 42
pi[1] = 43;
...
Which essently is the same as doing
*((int *) (pi + 0)) = 42;
*((int *) (pi + 1)) = 43;
which indeed does not make sense really as pi already is int*, so the fully correct approach (also taking into account the 2nd dimension) would be:
((int *)(ppv[0]))[0] = 42;
((int *)(ppv[0]))[1] = 43;
Which could be made usable by definging a macro:
#define GENERIC_ARRAY_ELEMENT(type, address, r, c) \
((type *)(address[r]))[c]
GENERIC_ARRAY_ELEMENT(int, ppv, 0, 0) = 42;
GENERIC_ARRAY_ELEMENT(int, ppv, 0, 1) = 43;
I will address the problem of allocation an array of void pointers and then interpreting them as an array of int pointers.
int **nope = (int **)mdeclaraMatrice(n,m,sizeof(int));
Even assuming the allocation was completely correct the assignment and later usage of nope is undefined behavior. void** and int** have incompatible types.
What you can do is the following. Assign the void pointers one by one to an array of int pointers.
void** arrp = mdeclaraMatrice(n,m,sizeof(int));
int* arr[n] ;
for( size_t i = 0 , i < n ; i++ )
arr[i] = arrp[i] ;
And then use the arr array, When you want to free the memory you free the original pointer:
free( arrp ) ;
The problem occurs in this line:
*(m + (i*4)) = malloc(nrColoane * sizeOfElement);
You have to know that when adding a number to an address, the address will be incremented by the number times the size of the object the address points to. So if your pointer points to an object that is of size 4 bytes, and you add 1 to it, then the address will automatically be incremented by 4, not by 1. So you should abandon *4.
Also, use the sizeof operator when allocating space, because addresses (and thus pointers) can have different sizes on different processor architectures.
Actually, you don't even need your generic 2D array function if you know the powerfull VLA features of C99. To allocate a true 2D array (no index array required), you just do this:
int (*twoDIntArray)[width] = malloc(height*sizeof(*twoDIntArray));
That's it. Accesses are just as simple:
twoDIntArray[line][column] = 42;
In this code, twoDIntArray is a pointer to an array of width integers. The malloc() call simply allocates enough space for height such line arrays. When you do the pointer arithmetic twoDIntArray[line], you add the size of line line arrays to the pointer, which produces the address of the corresponding line array. This line array is then indexed by the second array subscript [column].
Needless to say that freeing such an array is just as trivial:
free(twoDIntArray);

C - Segmentation Fault with dynamic allocations

I'm doing this program to find the saddle point of a matrix (elements there are the greatest number on their column and at the same time the smallest on their row)
So, here is the thing, I'm getting a Segmentation Fault. When using windows, it works fine actually, but when I'm going to run on Ubunto, it doesn't work. I, unfortunitely, only have windows on my machine, so I can't figure out why it is not working or where it is going wrong.
Could you guys help me out? Tell me what is wrong with the code, or where is the error please!
int main(){
int i, j, *ml, *mc, key = 1, z;
int ordem, **me;
char car;
/* ml = smallest of each row, mc = greatest of each column
* me = given matrix
* ordem = size of matrix */
scanf("%d", &ordem);
me = malloc(ordem * sizeof(int));
for(i = 0; i < ordem; i++){
me[i] = malloc(ordem * sizeof(int));
}
ml = malloc (ordem * sizeof(int));
mc = malloc (ordem * sizeof(int));
for(i = 0; i < ordem; i++){
scanf("%d", &me[i][0]);
for(j = 1; j < ordem; j++){
scanf(" %d", &me[i][j]);
}
do{
z = scanf("%c", &car);
}while ((z != EOF) && (car != '\n'));
}
If necessary, I can give you guys the rest of the code, but I'm quite sure that the error is happening in there, either on the malloc or the scanf.
Thanks a lot, really appreciate any help! Best regards!
int **me;
me = malloc(ordem * sizeof(int));
here is the mistake ! It's :
me = malloc(ordem * sizeof(int*));
Always double check your malloc, 90% of the segfault comme from here ...
Your issue is probably on the line
me = malloc(ordem * sizeof(int));
me is a int**, so you need to allocate for int*, not int.
This is giving you portability issues because different compilers do not necessarily use the same size for those data types. Try running this code on the different machines to test what is going on.
printf("The size of an int is %d\n", sizeof(int));
printf("The size of an int* is %d\n", sizeof(int*));
A way that you can modify your coding style so that this error is harder to make is to use the variable name in your sizeof like so
me = malloc(ordem * sizeof(*me));
This way you can visually see that you are allocating space for ordem variables of the type that me points to.
When you allocate the pointer array you need to take the element size of the pointer, not int. On your Ubuntu system the pointer size is probably 64 bit while ints are still 32, while on Windows both have the same size as was traditionally the case.

Segmentation fault (core dumped) [Conway's game of life]

I'm working on a C implementation for Conway's game of life, I have been asked to use the following header:
#ifndef game_of_life_h
#define game_of_life_h
#include <stdio.h>
#include <stdlib.h>
// a structure containing a square board for the game and its size
typedef struct gol{
int **board;
size_t size;
} gol;
// dynamically creates a struct gol of size 20 and returns a pointer to it
gol* create_default_gol();
// creates dynamically a struct gol of a specified size and returns a pointer to it.
gol* create_gol(size_t size);
// destroy gol structures
void destroy_gol(gol* g);
// the board of 'g' is set to 'b'. You do not need to check if 'b' has a proper size and values
void set_pattern(gol* g, int** b);
// using rules of the game of life, the function sets next pattern to the g->board
void next_pattern(gol* g);
/* returns sum of all the neighbours of the cell g->board[i][j]. The function is an auxiliary
function and should be used in the following function. */
int neighbour_sum(gol* g, int i, int j);
// prints the current pattern of the g-board on the screen
void print(gol* g);
#endif
I have added the comments to help out with an explanation of what each bit is.
gol.board is a 2-level integer array, containing x and y coordinates, ie board[x][y], each coordinate can either be a 1 (alive) or 0 (dead).
This was all a bit of background information, I'm trying to write my first function create_default_gol() that will return a pointer to a gol instance, with a 20x20 board.
I then attempt to go through each coordinate through the 20x20 board and set it to 0, I am getting a Segmentation fault (core dumped) when running this program.
The below code is my c file containing the core code, and the main() function:
#include "game_of_life.h"
int main()
{
// Create a 20x20 game
gol* g_temp = create_default_gol();
int x,y;
for (x = 0; x < 20; x++)
{
for (y = 0; y < 20; y++)
{
g_temp->board[x][y] = 0;
}
}
free(g_temp);
}
// return a pointer to a 20x20 game of life
gol* create_default_gol()
{
gol* g_rtn = malloc(sizeof(*g_rtn) + (sizeof(int) * 20 * 20));
return g_rtn;
}
This is the first feature I'd like to implement, being able to generate a 20x20 board with 0's (dead) state for every coordinate.
Please feel free to criticise my code, I'm looking to determine why I'm getting the segmentation fault, and if I'm allocating memory properly in the create_default_gol() function.
Thanks!
The type int **board; means that board must contain an array of pointers, each of which points to the start of each row. Your existing allocation omits this, and just allocates *g_rtn plus the ints in the board.
The canonical way to allocate your board, supposing that you must stick to the type int **board;, is:
gol* g_rtn = malloc(sizeof *g_rtn);
g_rtn->size = size;
g_rtn->board = malloc(size * sizeof *g_rtn->board);
for (int i = 0; i < size; ++i)
g_rtn->board[i] = malloc(size * sizeof **g_rtn->board);
This code involves a lot of small malloc chunks. You could condense the board rows and columns into a single allocation, but then you also need to set up pointers to the start of each row, because board must be an array of pointers to int.
Another issue with this approach is alignment. It's guaranteed that a malloc result is aligned for any type; however it is possible that int has stricter alignment requirements than int *. My following code assumes that it doesn't; if you want to be portable then you could add in some compile-time checks (or run it and see if it aborts!).
The amount of memory required is the sum of the last two mallocs:
g_rtn->board = malloc( size * size * sizeof **g_rtn->board
+ size * sizeof *g_rtn->board );
Then the first row will start after the end of the row-pointers (a cast is necessary because we are converting int ** to int *, and using void * means we don't have to repeat the word int):
g_rtn->board[0] = (void *) (g_rtn->board + size);
And the other rows each have size ints in them:
for (int i = 1; i < size; ++i)
g_rtn->board[i] = g_rtn->board[i-1] + size;
Note that this is a whole lot more complicated than just using a 1-D array and doing arithmetic for the offsets, but it was stipulated that you must have two levels of indirection to access the board.
Also this is more complicated than the "canonical" version. In this version we are trading code complexity for the benefit of having a reduced number of mallocs. If your program typically only allocates one board, or a small number of boards, then perhaps this trade-off is not worth it and the canonical version would give you fewer headaches.
Finally - it would be possible to allocate both *g_rtn and the board in the single malloc, as you attempted to do in your question. However my advice (based on experience) is that it is simpler to keep the board separate. It makes your code clearer, and your object easier to use and make changes to, if the board is a separate allocation to the game object.
create_default_gol() misses to initialise board, so applying the [] operator to it (in main() ) the program accesses "invaid" memory and with ethis provokes undefined behaviour.
Although enough memory is allocated, the code still needs to make board point to the memory by doing
gol->board = ((char*) gol) + sizeof(*gol);
Update
As pointed out by Matt McNabb's comment board points to an array of pointers to int, so initialisation is more complicate:
gol * g_rtn = malloc(sizeof(*g_rtn) + 20 * sizeof(*gol->board));
g_rtn->board = ((char*) gol) + sizeof(*gol);
for (size_t i = 0; i<20; ++i)
{
g_rtn->board[i] = malloc(20 * sizeof(*g_rtn->board[i])
}
Also the code misses to set gol's member size. From what you tell us it is not clear whether it shall hold the nuber of bytes, rows/columns or fields.
Also^2 coding "magic numbers" like 20 is bad habit.
Also^3 create_default_gol does not specify any parameters, which explictily allows any numberm and not none as you might perhaps have expected.
All in all I'd code create_default_gol() like this:
gol * create_default_gol(const size_t rows, const size_t columns)
{
size_t size_rows = rows * sizeof(*g_rtn->board));
size_t size_column = columns * sizeof(**g_rtn->board));
gol * g_rtn = malloc(sizeof(*g_rtn) + size_rows);
g_rtn->board = ((char*) gol) + sizeof(*gol);
if (NULL ! = g_rtn)
{
for (size_t i = 0; i<columns; ++i)
{
g_rtn->board[i] = malloc(size_columns); /* TODO: Add error checking here. */
}
g_rtn->size = size_rows * size_columns; /* Or what ever this attribute is meant for. */
}
return g_rtn;
}
gol* create_default_gol()
{
int **a,i;
a = (int**)malloc(20 * sizeof(int *));
for (i = 0; i < 20; i++)
a[i] = (int*)malloc(20 * sizeof(int));
gol* g_rtn = (gol*)malloc(sizeof(*g_rtn));
g_rtn->board = a;
return g_rtn;
}
int main()
{
// Create a 20x20 game
gol* g_temp = create_default_gol();
int x,y;
for (x = 0; x < 20; x++)
{
for (y = 0; y < 20; y++)
{
g_temp->board[x][y] = 10;
}
}
for(x=0;x<20;x++)
free(g_temp->board[x]);
free(g_temp->board);
free(g_temp);
}
main (void)
{
gol* gameOfLife;
gameOfLife = create_default_gol();
free(gameOfLife);
}
gol* create_default_gol()
{
int size = 20;
gol* g_rtn = malloc(sizeof *g_rtn);
g_rtn = malloc(sizeof g_rtn);
g_rtn->size = size;
g_rtn->board = malloc(size * sizeof *g_rtn->board);
int i, b;
for (i = 0; i < size; ++i){
g_rtn->board[i] = malloc(sizeof (int) * size);
for(b=0;b<size;b++){
g_rtn->board[i][b] = 0;
}
}
return g_rtn;
}
Alternatively, since you also need to add a create_gol(size_t new_size) of custom size, you could also write it as the following.
main (void)
{
gol* gameOfLife;
gameOfLife = create_default_gol();
free(gameOfLife);
}
gol* create_default_gol()
{
size_t size = 20;
return create_gol(size);
}
gol* create_gol(size_t new_size)
{
gol* g_rtn = malloc(sizeof *g_rtn);
g_rtn = malloc(sizeof g_rtn);
g_rtn->size = new_size;
g_rtn->board = malloc(size * sizeof *g_rtn->board);
int i, b;
for (i = 0; i < size; ++i){
g_rtn->board[i] = malloc(sizeof (int) * size);
for(b=0;b<size;b++){
g_rtn->board[i][b] = 0;
}
}
return g_rtn;
}
Doing this just minimizes the amount of code needed.

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.
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
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.
malloc() is not guaranteed to zero the memory. Use calloc() to allocate memory with zeros.
malloc does not initiate with 0's (because of performance issues... it's not always what you want)...
use calloc() instead.
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.
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);

Resources