How to free my double pointer allocated with malloc in another function - c

I want to free the double pointer, the problem is I was receiving as parameter another double pointer which actually makes a copy of the one I wanna free but that means it doesn't actually free the original, so how can I free the original in another function.
I've tried passing a double pointer as argument and a pointer pointing to this double pointer too but none of this worked.
int main(){
int ** matrix;
int rows = 5;
int cols = 6;
matrix = createMatrix(rows, cols);
printf("%d\n", matrix[2][3]);
freeMatrix(matrix, rows);
printf("%d\n", matrix[2][3]);
}
int** createMatrix(int row, int col){
int **m = (int **)malloc(row * sizeof(int*));
for(int x = 0; x < row; x++){
m[x] = (int *)malloc(col * sizeof(int));
}
return m;
}
void freeMatriz(int **m, int row){
for(int x = 0; x < row; x++){
free(m[x]);
}
free(m);
}
I was trying to print a position, lets say matrix[2][3] before and after the free; but both times its printing the number when after the print it shouldn't because that space in memory its supposed to be freed which apparently is not happening.

other than the typo in the
void freeMatriz(int **m, int row)
^
This is correctly freeing up the memory. The printf after freeing the matrix should actually result in an access violation. Which when testing with a MUCH larger 1024x2048 matrix this is what happens. My theories are as follows...
The memory has not yet been reclaimed and was still within program reach...
Some sort of delay in garbage collection or something.. lol
I'll leave it up to someone who might know why the second printf worked with such a small memory space being allocated to do so.. ;) would love to know the exact reason..
if you step through this with a debugger you will see the memory does get freed properly and if stepped through with a debugger the second printf results in an access violation... so it's gotta have something to do with the kernel.. :)
If you look at the Working Set and the Memory allocation in task manager, and put a system("pause") or getchar() (whatever type of break you want) before the free.. you can allocate a large matrix, check in in task manager... resume the program (with another break after the free). and you will see that the memory is being released. :)

Your two primary problems are:
You fail to validate the return of each allocation so malloc could have failed and you would have no way of knowing; and
After allocating storage for your integer values, you fail to initialize the memory, leaving the memory holding whatever garbage values happened to be present at that memory location (you can, and in the case of your integer allocations, use calloc to allocate and initialize at the same time, or use memset to do the same)
Your attempt to access matrix[2][3] before free() was simply accessing a uninitialized 4-bytes of memory containing whatever bits happened to be there. Your attempt to access matrix[2][3] after free() invokes Undefined Behavior. After free(), you can no longer validly access the memory that has been freed.
If you allocate, you must validate... It's not a matter of if malloc can fail returning NULL, it is a matter of when malloc fails returning NULL. To handle the failure case, you must always check the return of the allocation function (just as you do with every input function) you use. It is simple, if malloc returns NULL the allocation failed. So just check, e.g.
int **creatematrix (int row, int col)
{
int **m = malloc (row * sizeof *m);
if (!m) { /* if you allocate -- you must VALIDATE */
perror ("malloc-m");
return NULL;
}
for (int x = 0; x < row; x++) {
if (!(m[x] = malloc (col * sizeof *m[x]))) { /* ditto */
perror ("malloc-m[x]");
while (x--) /* on error free any allocated memory */
free (m[x]);
free (m); /* before returing NULL */
return NULL;
}
}
return m;
}
(note: before returning NULL you should free() any memory you have allocated up to that point to prevent a memory leak when you return NULL)
In your calling function (main() here), you need to validate the return of your creatematrix function to determine success/failure of the allocate -- before you make use of the memory, e.g.
int main (void) {
int **matrix,
rows = 5,
cols = 6;
if (!(matrix = creatematrix (rows, cols))) /* VALIDATE allocations */
exit (EXIT_FAILURE);
for (int i = 0; i < rows; i++) { /* loop initializing all values */
for (int j = 0; j < cols; j++) {
matrix[i][j] = i * cols + j;
printf (" %3d", matrix[i][j]); /* output all values */
}
putchar ('\n');
}
freematrix (matrix, rows); /* free all allocated memory */
}
Now you can free() all memory (which except for the typo of 'z' instead of 'x' you were doing correctly). Putting it altogether you could do:
#include <stdio.h>
#include <stdlib.h>
int **creatematrix (int row, int col)
{
int **m = malloc (row * sizeof *m);
if (!m) { /* if you allocate -- you must VALIDATE */
perror ("malloc-m");
return NULL;
}
for (int x = 0; x < row; x++) {
if (!(m[x] = malloc (col * sizeof *m[x]))) { /* ditto */
perror ("malloc-m[x]");
while (x--) /* on error free any allocated memory */
free (m[x]);
free (m); /* before returing NULL */
return NULL;
}
}
return m;
}
void freematrix (int **m, int row)
{
for (int x = 0; x < row; x++)
free (m[x]);
free (m);
}
int main (void) {
int **matrix,
rows = 5,
cols = 6;
if (!(matrix = creatematrix (rows, cols))) /* VALIDATE allocations */
exit (EXIT_FAILURE);
for (int i = 0; i < rows; i++) { /* loop initializing all values */
for (int j = 0; j < cols; j++) {
matrix[i][j] = i * cols + j;
printf (" %3d", matrix[i][j]); /* output all values */
}
putchar ('\n');
}
freematrix (matrix, rows); /* free all allocated memory */
}
Example Use/Output
$ ./bin/freematrix
0 1 2 3 4 5
6 7 8 9 10 11
12 13 14 15 16 17
18 19 20 21 22 23
24 25 26 27 28 29
Memory Use/Error Check
In any code you write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.
It is imperative that you use a memory error checking program to insure you do not attempt to access memory or write beyond/outside the bounds of your allocated block, attempt to read or base a conditional jump on an uninitialized value, and finally, to confirm that you free all the memory you have allocated.
For Linux valgrind is the normal choice. There are similar memory checkers for every platform. They are all simple to use, just run your program through it.
$ valgrind ./bin/freematrix
==17080== Memcheck, a memory error detector
==17080== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==17080== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==17080== Command: ./bin/freematrix
==17080==
0 1 2 3 4 5
6 7 8 9 10 11
12 13 14 15 16 17
18 19 20 21 22 23
24 25 26 27 28 29
==17080==
==17080== HEAP SUMMARY:
==17080== in use at exit: 0 bytes in 0 blocks
==17080== total heap usage: 6 allocs, 6 frees, 160 bytes allocated
==17080==
==17080== All heap blocks were freed -- no leaks are possible
==17080==
==17080== For counts of detected and suppressed errors, rerun with: -v
==17080== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Always confirm that you have freed all memory you have allocated and that there are no memory errors.
Look things over and let me know if you have further questions.

Related

Segmentation fault when using sprintf in dynamically allocated array

I am converting integers to strings and adding them to a dynamically allocated array. The problem is that it is causing a segfault. I don't understand why it is happening.
#include <stdio.h>
#include <stdlib.h>
int main() {
char *x = malloc(10 * sizeof(char));
x[0] = malloc(10 * sizeof(char));
sprintf(x[0],"%d",10);
for(int i = 0; i < 10;i++){
free(x[i]);
}
free(x);
return 0;
}
To allocate an array whose elements are char*, the pointer to point the array should be char**, not char*.
Also you mustn't use values in buffer allocated via malloc() and not initiaized. The values are indeterminate and using them invokes undefined behavior.
#include <stdio.h>
#include <stdlib.h>
int main() {
/* correct type here (both variable and allocation size) */
char **x = malloc(10 * sizeof(char*));
x[0] = malloc(10 * sizeof(char));
sprintf(x[0],"%d",10);
/* initialize the other elements to pass to free() */
for (int i = 1; i < 10; i++) x[i] = NULL;
for(int i = 0; i < 10;i++){
free(x[i]);
}
free(x);
return 0;
}
If you want a dynamic allocated array of strings, you should declare your variable x as a pointer to an array of e.g. 32 chars. The you can allocate/deallocate an array of these using a single malloc and likewise a single free.
Like:
#define NUM_STRINGS 10
#define STRING_SIZE 32
int main() {
// declare x as a pointer to an array of STRING_SIZE chars
char (*x)[STRING_SIZE];
// Allocate space for NUM_STRINGS of the above array, i.e.
// allocate an array with NUM_STRINGS arrays of STRING_SIZE chars
x = malloc(NUM_STRINGS * sizeof *x);
if (x)
{
for (int i = 0; i < NUM_STRINGS; ++i)
{
sprintf(x[i], "%d", 10 + i);
}
for (int i = 0; i < NUM_STRINGS; ++i)
{
puts(x[i]);
}
free(x);
}
return 0;
}
Output:
10
11
12
13
14
15
16
17
18
19
The best way to determine the amount of memory to be used with malloc is this:
#include <stdio.h>
#include <stdlib.h>
#define N_STRINGS 10
#define STRING_SZ 10
int main() {
// if you use *x (the deferred subexpression) the compiler can calculate its
// sizeof easily, and no need to use a constant or something that has to be
// revised if you change the type of x. Also, calloc will give instead N_STRINGS
// pointers already initialized to NULL.
char **x = calloc(N_STRINGS, sizeof *x);
// to be able to free(x[i]) for all i, you need to initialize all pointers,
// and not only the first one.
int i; // I prefer this, instead of for(int i..., which is more portable with legacy code.
for (i = 0; i < N_STRINGS; i++) {
// char is warranted to be sizeof 1, you don't need to specify but the
// number of chars you want for each character array.
x[i] = malloc(STRING_SZ); // remember only STRING_SZ chars you have, so...
// better to use snprintf(), instead.
snprintf(x[i], // the buffer pointer
STRING_SZ, // the buffer size (STRING_SZ chars, incl. the final null char)
"%d", // the format string
10); // initialize all strings to the string "10" ???
}
// upto here we have made N_STRINGS + 1 calls to malloc...
// you should do something here to check that the allocations went fine, like
// printing the values or do some work on the strings, but that's up to you.
// now, everything should be fine for free() to work.
for(int i = 0; i < N_STRINGS; i++){
free(x[i]);
}
free(x); // ... and this is the N_STRINGS + 1 call to free.
return 0;
}
Check always that the number of free calls executed by your program has to be the same of the malloc calls you have made (before). A free call must free the memory allocated by one (and only one) call to malloc. You cannot free something that has not been acquired by malloc() (or calloc()) directly or indirectly. The same as it is bad use (but not necessary an error) to do a malloc that is not freed before the program ends (this is not true in non-hosted environments, e.g. embedded programs, in which the operating system doesn't deallocate the memory used by a program when it finishes, although)
By the way, the reason of your segmentation fault is precisely that you have made only two calls to malloc(), but you made 11 calls to free(). free() tries to free memory that malloc() has not allocated, or even worse, you don't own. Anyway, this drives you to Undefined Behaviour, which is something you don't desire in a program. In this case, you got a program crash.

Defining two pointers in C-programming for dynamic array allocation

(edit)
can someone help me to understand why the allocation of a dynamic array is based on two pointers ( this code works without any problem)
int main(int argc, char** argv) {
int i;
int n=3;
int* *t1;
*t1 = (int*) malloc(n*sizeof(int));
for (i = 0 ; i <n ; i++)
{
scanf("%d",(*t1+i));
}
for ( i=0; i<n; i++)
{
printf("%d",*(*t1+i));
}
while the only writing that i know is
int* t;
t = (int*) malloc(n*sizeof(int));
so what is the interest of using *t instead of t.
Thank you.
Your question is unclear because you haven't specified what it is you are attempting to achieve. Later in a comment, you indicate you need a simple 1D array, but that isn't included in your question. Let's cover both case plus the case of using a pointer-to-array and make sure you understand the basics.
To understand dynamic allocation, you must understand there are no arrays involved (the exception being allocating for a pointer-to-array of fixed size).
Otherwise, dynamic allocation encompasses allocation of a block of memory of a given size and assignment of the starting address for that new block of memory to a pointer. In C, there is no need to cast the return of malloc, it is unnecessary. See: Do I cast the result of malloc? (in C++ it is required)
Allocating Memory For Integers
When you want to allocate a block of memory for the storage of integers, you simply allocate a block big enough to hold the number of integers you want to store, and assign the starting address for the new block of memory to a pointer. Let's take it step-by-step:
int *t;
declares a pointer-to int to which the beginning address for an allocated block of memory can be assigned.
int n = 100;
t = malloc (n * sizeof *t);
malloc allocates a new block of memory of n * sizeof *t bytes which is sufficient in size to hold n integer values and the beginning address for that block is assigned to the pointer t. Using the dereferenced sizeof *t to set the type-size ensures your type-size is correct. (t being a pointer-to int, when you dereference t (e.g. *t), your type is plain-old int, so sizeof *t is equivalent to sizeof (int))
It may not seem like it matters now (and for trivial types it doesn't make a lot of difference), but as the type of objects you deal with grow in complexity and levels of pointer indirection, mistakenly setting an incorrect type-size becomes a common problem with dealing with allocated nested structures, etc.. That is why simply using the dereferenced pointer to set type-size is recommended.
Let's take a simple example that users a pointer int *t_1D; to emphasize it is single linear allocation that can be indexed as a simple 1D array:
#define NUMINT 50 /* number of integers for t_1D */
...
int main (void) {
int *t_1D = NULL; /* pointer to int */
t_1D = malloc (NUMINT * sizeof *t_1D); /* allocate storage for NUMINT int */
if (t_1D == NULL) { /* validate EVERY allocation, handle error */
perror ("malloc-t_1D");
return 1;
}
for (int i = 0; i < NUMINT; i++)
t_1D[i] = i + 1; /* assign a value to each integer */
puts ("\nvalues in t_1D (with \\n every 5th integer)\n");
for (int i = 0; i < NUMINT; i++) { /* loop over each value */
if (i && i % ARRSZ == 0) /* simple mod test to output newline */
putchar ('\n');
printf (" %3d", t_1D[i]); /* output value at address */
}
puts ("\n");
free (t_1D); /* don't forget to free what you allocate */
Above when you are done with that block of memory, you must free() the block to prevent a memory leak. Understand for trivial examples where you allocate in main() the memory is freed on program exit. However, it is important to develop good habits early as you will commonly be allocating in a function all and if the memory is not freed before your function returns (or later freed in the caller before it returns) you lose the pointer to the block and it cannot be free -- resulting in a memory leak.
Simulating a 2D Array with a Pointer-To-Pointer
If you use a pointer-to-pointer (e.g. int **t;) as your pointer, your allocation is a two-step process. First you allocate a block of memory to hold some number of pointers (which you generally think of as the number of rows for the object you are allocating).
Then in a second set of allocations, you will allocate a block of memory to hold the number of integers-per-row you wish to store per-row (generally thought of as the col (column) number of integers) and assign the starting address for each allocated block to one of your allocated pointers -- in sequence.
The result is a data structure where you allocate 1-block of memory to hold row number pointers and and row blocks of memory to hold col number of integers. Then you can access each of the memory locations just as you would access values in a 2D array.
However, note since there are multiple allocations required to create an object from a pointer-to-pointer, there will be multiple calls to free required to free the memory allocated to the object.
Now let's look at how that can be used. Below, we will use int **t_2D; as the variable name to indicate we are storing an object that we can index as a 2D array:
#define ARRSZ 5 /* number of integers per-row for t_2D and t_PTA */
...
int **t_2D = NULL; /* pointer to pointer to int */
...
/* a pointer to pointer (allocate pointers, then ints for each pointer) */
t_2D = malloc (NUMINT/ARRSZ * sizeof *t_2D); /* allocate 10 pointers */
if (!t_2D) { /* validate EVERY allocation */
perror ("malloc-t_2D");
return 1;
}
for (int i = 0; i < NUMINT/ARRSZ; i++)
/* allocate/validate storage for 5 int assign start address to each ptr */
if (!(t_2D[i] = malloc (ARRSZ * sizeof *t_2D[i]))) { /* on failure */
while (i--) /* free previously allocated block for int */
free (t_2D[i]);
free (t_2D); /* free pointers */
return 1;
}
for (int i = 0; i < NUMINT/ARRSZ; i++) /* loop over pointers */
for (int j = 0; j < ARRSZ; j++) /* loop over integer storage */
t_2D[i][j] = (i * ARRSZ) + j + 1; /* assign value for each int */
puts ("values in t_2D output by row x col:\n");
for (int i = 0; i < NUMINT/ARRSZ; i++) {
for (int j = 0; j < ARRSZ; j++)
printf (" %3d", t_2D[i][j]); /* output each integer */
putchar ('\n');
}
putchar ('\n');
for (int i = 0; i < NUMINT/ARRSZ; i++) /* loop over pointers */
free (t_2D[i]); /* free integers */
free (t_2D); /* free pointers */
Note the loop at the end that loops over each pointer freeing the storage for integers before calling free to free the block of memory holding the pointers themselves.
A Pointer-To-Array -- Single Allocation, Single-Free, 2D Indexing
There is one other common allocation that you will run into that warrants explanation. You can use a pointer-to-array of fixed length (e.g. int (*t_PTA)[CONST];) and then allocate storage for some number of the fixed arrays in a single call and be able to address the object as a 2D array just as was done above with t_2D. Since there is only a single-allocation required, there is only a single-free needed to free the memory associated with the object.
(note: do not confuse a poitner-to-array (e.g. int (*p)[CONST]) with an array-of-pointers (e.g. int *p[CONST]), they are two distinct types)
To allocate, use and free an object create from a pointer-to-array, you can do the following:
/* a pointer to array -- single allocation, single-free, 2D indexing */
int (*t_PTA)[ARRSZ] = NULL; /* pointer to array of int[ARRSZ] */
t_PTA = malloc (NUMINT/ARRSZ * sizeof *t_PTA); /* storage for 50 integers */
if (!t_PTA) { /* validate EVERY allocation */
perror ("malloc-t_2D");
return 1;
}
for (int i = 0; i < NUMINT/ARRSZ; i++) /* loop over pointers */
for (int j = 0; j < ARRSZ; j++) /* loop over integer storage */
t_PTA[i][j] = (i * ARRSZ) + j + 1; /* assign value for each int */
puts ("values in t_PTA output by row x col:\n");
for (int i = 0; i < NUMINT/ARRSZ; i++) {
for (int j = 0; j < ARRSZ; j++)
printf (" %3d", t_PTA[i][j]); /* output each integer */
putchar ('\n');
}
putchar ('\n');
free (t_PTA);
(note: the convenience of the single free (t_PTA); used to free all memory associated with the object.)
Now let's put it altogether in a workable example:
#include <stdio.h>
#include <stdlib.h>
#define ARRSZ 5 /* number of integers per-row for t_2D and t_PTA */
#define NUMINT 50 /* number of integers for t_1D */
int main (void) {
int *t_1D = NULL, /* pointer to int */
**t_2D = NULL, /* pointer to pointer to int */
(*t_PTA)[ARRSZ] = NULL; /* pointer to array of int[ARRSZ] */
/* handling simple storage for integers */
t_1D = malloc (NUMINT * sizeof *t_1D); /* allocate storage for NUMINT int */
if (t_1D == NULL) { /* validate EVERY allocation, handle error */
perror ("malloc-t_1D");
return 1;
}
for (int i = 0; i < NUMINT; i++)
t_1D[i] = i + 1; /* assign a value to each integer */
puts ("\nvalues in t_1D (with \\n every 5th integer)\n");
for (int i = 0; i < NUMINT; i++) { /* loop over each value */
if (i && i % ARRSZ == 0) /* simple mod test to output newline */
putchar ('\n');
printf (" %3d", t_1D[i]); /* output value at address */
}
puts ("\n");
free (t_1D); /* don't forget to free what you allocate */
/* a pointer to pointer (allocate pointers, then ints for each pointer) */
t_2D = malloc (NUMINT/ARRSZ * sizeof *t_2D); /* allocate 10 pointers */
if (!t_2D) { /* validate EVERY allocation */
perror ("malloc-t_2D");
return 1;
}
for (int i = 0; i < NUMINT/ARRSZ; i++)
/* allocate/validate storage for 5 int assign start address to each ptr */
if (!(t_2D[i] = malloc (ARRSZ * sizeof *t_2D[i]))) { /* on failure */
while (i--) /* free previously allocated block for int */
free (t_2D[i]);
free (t_2D); /* free pointers */
return 1;
}
for (int i = 0; i < NUMINT/ARRSZ; i++) /* loop over pointers */
for (int j = 0; j < ARRSZ; j++) /* loop over integer storage */
t_2D[i][j] = (i * ARRSZ) + j + 1; /* assign value for each int */
puts ("values in t_2D output by row x col:\n");
for (int i = 0; i < NUMINT/ARRSZ; i++) {
for (int j = 0; j < ARRSZ; j++)
printf (" %3d", t_2D[i][j]); /* output each integer */
putchar ('\n');
}
putchar ('\n');
for (int i = 0; i < NUMINT/ARRSZ; i++) /* loop over pointers */
free (t_2D[i]); /* free integers */
free (t_2D); /* free pointers */
/* a pointer to array -- single allocation, single-free, 2D indexing */
t_PTA = malloc (NUMINT/ARRSZ * sizeof *t_PTA); /* storage for 50 integers */
if (!t_PTA) { /* validate EVERY allocation */
perror ("malloc-t_2D");
return 1;
}
for (int i = 0; i < NUMINT/ARRSZ; i++) /* loop over pointers */
for (int j = 0; j < ARRSZ; j++) /* loop over integer storage */
t_PTA[i][j] = (i * ARRSZ) + j + 1; /* assign value for each int */
puts ("values in t_PTA output by row x col:\n");
for (int i = 0; i < NUMINT/ARRSZ; i++) {
for (int j = 0; j < ARRSZ; j++)
printf (" %3d", t_PTA[i][j]); /* output each integer */
putchar ('\n');
}
putchar ('\n');
free (t_PTA);
}
Where you compile and run to receive the following:
Example Use/Output
$ ./bin/dynalloc_1_2_pta
values in t_1D (with \n every 5th integer)
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
26 27 28 29 30
31 32 33 34 35
36 37 38 39 40
41 42 43 44 45
46 47 48 49 50
values in t_2D output by row x col:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
26 27 28 29 30
31 32 33 34 35
36 37 38 39 40
41 42 43 44 45
46 47 48 49 50
values in t_PTA output by row x col:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
26 27 28 29 30
31 32 33 34 35
36 37 38 39 40
41 42 43 44 45
46 47 48 49 50
Memory Use/Error Check
It is imperative that you use a memory error checking program to ensure you do not attempt to access memory or write beyond/outside the bounds of your allocated block, attempt to read or base a conditional jump on an uninitialized value, and finally, to confirm that you free all the memory you have allocated.
For Linux valgrind is the normal choice. There are similar memory checkers for every platform. They are all simple to use, just run your program through it.
$ valgrind ./bin/dynalloc_1_2_pta
==10642== Memcheck, a memory error detector
==10642== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==10642== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==10642== Command: ./bin/dynalloc_1_2_pta
==10642==
values in t_1D (with \n every 5th integer)
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
26 27 28 29 30
31 32 33 34 35
36 37 38 39 40
41 42 43 44 45
46 47 48 49 50
values in t_2D output by row x col:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
26 27 28 29 30
31 32 33 34 35
36 37 38 39 40
41 42 43 44 45
46 47 48 49 50
values in t_PTA output by row x col:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
26 27 28 29 30
31 32 33 34 35
36 37 38 39 40
41 42 43 44 45
46 47 48 49 50
==10642==
==10642== HEAP SUMMARY:
==10642== in use at exit: 0 bytes in 0 blocks
==10642== total heap usage: 14 allocs, 14 frees, 1,704 bytes allocated
==10642==
==10642== All heap blocks were freed -- no leaks are possible
==10642==
==10642== For counts of detected and suppressed errors, rerun with: -v
==10642== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Always confirm that you have freed all memory you have allocated and that there are no memory errors.
It is a lot to digest at one sitting, but take it piece-by-piece and dynamic allocation will start to make sense. Let me know if you have furher questions.
In the first case t is a pointer to int*. And the right way would be for allocation:
int **t;
t = (int**) malloc(n*sizeof(int*));
So in other word: it is an array of int*, which is the dynamically allocated version of int* t[n].
And this is different, than the second case, where t is a pointer to int type, basically t is an array of int in this case, which is like the dynamically allocated version of int t[n].
Please clarify. However, the first version is incorrect. If you want to allocate a array of pointers to arrays, you should be doing:
int **t;
t=(int**) malloc(n*sizeof(int*));
To allocate the array of pointers to each individual row, and then allocating the rows:
for (int i=0; i<n; ++i){
t[i] = (int*) malloc(n*sizeof(int));
}
*t won't be valid in your first snippet, since it can be accessed. You would have to allocate **t first.
An int** would be is used when you want to allocate a block of int* objects. In your example, that is not what you have done or indeed want.
In fact you have not allocated or assigned anything to t1, making the allocation to *t1 (i.e. t1[0]) invalid because t1 is itself unknown.
If for example you wanted an allocated array of pointers to multiple allocated int arrays, then int** would be the appropriate data type for the array of pointers to arrays of int:
// Allocate n arrays of m ints
int** t = malloc( sizeof(int*) * n ) ;
for( int i = 0; i < n; i++ )
{
t[i] = malloc( sizeof(int) * m ) ;
}
Then for example t[2][3] refers to the fourth element in the third block of of int.
It is not an issue of syntax; they are not different forms of the same thing; they are semantically different, and in the context of your example int** is inappropriate and semantically incorrect.

No access to dynamically allocated array of 2 dimensions [duplicate]

This question already has an answer here:
Dynamic memory access only works inside function
(1 answer)
Closed 3 years ago.
I'm experimenting with the dynamic memory allocation of variable sized arrays. The function "ft_ultimate_range" seems to work, however, a problem arises when I try to access and print the values of each array's array. It signals either segmentation fault: 11, when compiled with GCC, or "subscripted value is neither array nor pointer nor vector" with [http://pythontutor.com/c][1]. I understand that this has to do with the use- or abuse of pointers... ehm
// allocate a grid of [n][n] with numbers ranging max-min
int *ft_ultimate_range(int **range, int min, int max)
{
int len, *ptr;
int count = min;
len = max - min;
ptr = range;
// allocate memory **arr
range = malloc(len * sizeof * range);
for(int i = 0; i < len; i++) {
range[i] = malloc(len * sizeof * ptr);
}
// assign values to allocated memory location
for(int i = 0; i < len; i++) {
for(int j = 0; j < len; j++) {
range[i][j] = count++;
}
count = min;
}
// free memory **range
for(int i = 0; i < len; i++) {
free(range[i]);
}
free(range);
return ptr;
}
int main()
{
int n;
n = 6 - 3;
int **ptr, *arr;
arr = ft_ultimate_range(ptr, 3, 6);
// print
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
printf("%d", ptr[i][j]);
}
}
return 0;
}
...a little pointer in the right direction would be very much appreciated.
Well, it obvious you are quite lost regarding how to return an allocated grid (pointer-to-pointer-to-int) from ft_ultimate_range() to main().
To begin, you do not need to pass range as a parameter to ft_ultimate_range(). Instead, make the return type int ** and declare int **range within ft_ultimate_range() and then allocate len pointers, and then allocate len integers per-pointer, assign the values and then return range and assign it to arr in main(), e.g.
#include <stdio.h>
#include <stdlib.h>
/* allocate a grid of [n][n] with numbers ranging max-min */
int **ft_ultimate_range (int min, int max)
{
int len = max - min,
**range = NULL,
count = min;
/* allocate len pointers */
range = malloc (len * sizeof * range);
if (!range) { /* validate EVERY allocation */
perror ("malloc-range");
return NULL;
}
/* allocate len int per-pointer */
for (int i = 0; i < len; i++) {
range[i] = malloc (len * sizeof *range[i]);
if (!range[i]) { /* validate alloation */
perror ("malloc-range[i]");
while (i--) /* free previously allocated rows */
free (range[i]); /* free pointers */
free (range);
return NULL;
}
}
/* assign values to allocated memory location */
for(int i = 0; i < len; i++) {
for(int j = 0; j < len; j++) {
range[i][j] = count++;
}
count = min;
}
return range;
}
(note: you MUST VALIDATE EVERY ALLOCATION...)
In main(), you don't need ptr, all you need is the int** pointer you will assign the return from ft_ultimate_range() to, e.g.
int main (void) {
int n = 6 - 3;
int **arr;
arr = ft_ultimate_range (3, 6);
if (!arr) /* validate return */
return 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf (" %d", arr[i][j]);
}
putchar ('\n');
free (arr[i]);
}
free (arr);
return 0;
}
(note: similarly, you must validate the return of ft_ultimate_range() before blindly looping through the values (that will not be there if an allocation failed)).
Example Use/Output
$ ./bin/alloc_a_grid
3 4 5
3 4 5
3 4 5
Memory Use/Error Check
In any code you write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.
It is imperative that you use a memory error checking program to insure you do not attempt to access memory or write beyond/outside the bounds of your allocated block, attempt to read or base a conditional jump on an uninitialized value, and finally, to confirm that you free all the memory you have allocated.
For Linux valgrind is the normal choice. There are similar memory checkers for every platform. They are all simple to use, just run your program through it.
$ valgrind ./bin/alloc_a_grid
==29026== Memcheck, a memory error detector
==29026== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==29026== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==29026== Command: ./bin/alloc_a_grid
==29026==
3 4 5
3 4 5
3 4 5
==29026==
==29026== HEAP SUMMARY:
==29026== in use at exit: 0 bytes in 0 blocks
==29026== total heap usage: 4 allocs, 4 frees, 60 bytes allocated
==29026==
==29026== All heap blocks were freed -- no leaks are possible
==29026==
==29026== For counts of detected and suppressed errors, rerun with: -v
==29026== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Always confirm that you have freed all memory you have allocated and that there are no memory errors.
Look things over and let me know if you have further questions.
Here:
int **ptr, *arr;
arr = ft_ultimate_range(ptr, 3, 6);
ptr is NULL / uninitialised now. You cant allocate of this. malloc must be before call a function ft_ultimate_range. Here: printf("%d", ptr[i][j]); is NULL[i][j].
And you free **ptr in function ft_ultimate_range.
Hope this help.
int **ptr, *arr;
ptr is uninitialised at this point. It's value is indeterminate.
arr = ft_ultimate_range(ptr, 3, 6);
Passing an uninitialised value to a function is always wrong. If you hope the function will initialise it, you are mistaken. Read on pass by value.
ptr = range;
This assignment is wrong. You should have received a compiler warning about it. If you did not, upgrade your compiler ASAP. Never ignore warnings. Toying with a program that compiles with warnings is a waste of time.
for(int i = 0; i < len; i++) {
free(range[i]);
}
free(range);
At this point, every pointer in the program is invalid. Dereferencing them is undefined behaviour.
It isn't at all clear what your program is supposed to return. You are not using the return value anyway.
I suggest changing the signature of your function to this:
int** ft_ultimate_range(int min, int max)
Try to fit whatever you are trying to do in this mold.

How to print 2d matrices c

I am trying to simulate matrices using 2d arrays. But I am stuck at a run-time error. I am sure it occurs at printing function,but I couldn't find a solution at all.
obtn_matrix is a function that I use to create a matrix array. I didn't share the filler function which is used to get int values for the elements of the matrix array,so printed values will be whats in the memory. However, the problem is, I can't print the values at all. Program crashes after obtn_matrix.
int main()
{
int**matrix,m,n;
obtn_matrix(matrix,m,n);
prnt_matrix(matrix,m,n);
getch();
}
void prnt_matrix(int** matrix,int m,int n)
{
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
printf("%d ",matrix[i][j]);
}
printf("\n");
}
}
void obtn_matrix(int** matrix,int m,int n)
{
printf("Please enter the column number: ");
fflush(stdin);
scanf("%d",&m);
printf("Please enter the row number: ");
fflush(stdin);
scanf("%d",&n);
matrix=create_matrix(m,n);
}
The expected result is something like below:
4542 64 274 4234
765 53 3523 5345
5145 154 545 545
5435 543 545 14
I will handle the formatting (%4d etc). Kindly thanks in advance.
in obtn_matrix the assignment of matrix, m and n are not visible from main , you need to use pointer to them.
For instance, using array of int * because the dimensions are unknown at compile time:
#include <stdio.h>
#include <stdlib.h>
void prnt_matrix(int ** matrix,int m,int n)
{
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
printf("%d ",matrix[i][j]);
}
printf("\n");
}
}
int ** create_matrix(int m, int n)
{
int ** ma = calloc(m, sizeof(int*));
if (ma != NULL) {
int i, j;
for (i = 0; i != m; ++i) {
if ((ma[i] = malloc(n*sizeof(int))) == NULL)
return NULL;
for (j = 0; j != n; ++j) {
ma[i][j] = i*n + j;
}
}
}
return ma;
}
void obtn_matrix(int *** matrix,int * m,int * n)
{
printf("Please enter the row number: ");
fflush(stdin);
scanf("%d",m);
printf("Please enter the column number: ");
fflush(stdin);
scanf("%d",n);
*matrix=create_matrix(*m,*n);
}
void free_matrix(int ** matrix,int m,int n)
{
for(int i=0;i<m;i++)
{
if (matrix[i] == NULL)
/* matrix creation was aborted */
break;
free(matrix[i]);
}
free(matrix);
}
int main()
{
int ** matrix,m,n;
obtn_matrix(&matrix,&m,&n);
if (matrix != NULL) {
prnt_matrix(matrix,m,n);
free_matrix(matrix,m,n);
}
}
Compilation and execution :
pi#raspberrypi:~ $ gcc -pedantic -Wextra m.c
pi#raspberrypi:~ $ ./a.out
Please enter the row number: 3
Please enter the column number: 2
0 1
2 3
4 5
Execution under valgrind
pi#raspberrypi:~ $ valgrind ./a.out
==10436== Memcheck, a memory error detector
==10436== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==10436== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==10436== Command: ./a.out
==10436==
Please enter the row number: 3
Please enter the column number: 2
0 1
2 3
4 5
==10436==
==10436== HEAP SUMMARY:
==10436== in use at exit: 0 bytes in 0 blocks
==10436== total heap usage: 6 allocs, 6 frees, 2,084 bytes allocated
==10436==
==10436== All heap blocks were freed -- no leaks are possible
==10436==
==10436== For counts of detected and suppressed errors, rerun with: -v
==10436== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
Note it is also possible to just alloc one array of m*n int but in that case rather than to use m[i][j]you need to do m[i*n+j]
If you haven't fully wrapped your head around the basic problem you are having, the problem is this, C passes parameters to functions by value. What this means is that when a parameter is passed, the function receives a copy of the variable which it is free to change -- but any changes are lost when the function returns.
One caveat to this is when an allocated pointer is passed. While it is still passed by value and the pointer will have its very own and very different address from the original, the memory address it holds as its value will still point to the same address as it does in the caller. This is no different that assigning int a = 5; and then passing a as a parameter, the function receives a copy of the variable, but it still contains 5.
However, if you attempt to allocate or reallocate such that the address of the pointer is changed, then any changes made in the function will be lost on return and not visible in the caller.
How Do You Handle This?
You have two options (1) pass the address of the pointer, so any changes to the address can be assigned to the dereferenced pointer (i.e. the original pointer address), or (2) change the return type from void to the type of pointer that needs to be returned and return the newly allocated/reallocated pointer for assignment in the caller.
For example, in your case, you need not pass matrix as a parameter to obtn_matrix() at all. You can simply use option (2) above and change the return type of obtn_matrix() to int ** and return create_matrix (*m, *n); at the end, e.g.
int **create_matrix (int m, int n)
{
int **matrix = malloc (m * sizeof *matrix);
if (matrix == NULL) {
perror ("malloc-matrix");
return NULL;
}
for (int i = 0; i < m; i++)
/* use calloc to initialize values zero */
if ((matrix[i] = calloc (n, sizeof **matrix)) == NULL) {
perror ("malloc-matrix[n]");
return NULL;
}
return matrix;
}
/* use pointers as parameters so the updated values of m, n are
* available back in the caller after the function returns. return
* int** for assignment back in the caller. Avoids becoming a
* 3-Star Programmer (not a compliment). return NULL on failure.
*/
int **obtn_matrix (int *m, int *n)
{
fputs ("enter number of rows: ", stdout);
if (scanf ("%d", m) != 1) { /* validate ALL user-input */
fputs ("error: invalid number of rows.\n", stderr);
return NULL;
}
fputs ("enter number of cols: ", stdout);
if (scanf ("%d", n) != 1) {
fputs ("error: invalid number of cols.\n", stderr);
return NULL;
}
return create_matrix (*m, *n);
}
Now putting it altogether, and making note that #bruno explains why you must pass the address of m, n (e.g. &m, &n) to obtn_matrix (option (1) above) so the updated values of m & n are available back in main() (the caller here), you could do something like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int **create_matrix (int m, int n)
{
int **matrix = malloc (m * sizeof *matrix);
if (matrix == NULL) {
perror ("malloc-matrix");
return NULL;
}
for (int i = 0; i < m; i++)
/* use calloc to initialize values zero */
if ((matrix[i] = calloc (n, sizeof **matrix)) == NULL) {
perror ("malloc-matrix[n]");
return NULL;
}
return matrix;
}
/* use pointers as parameters so the updated values of m, n are
* available back in the caller after the function returns. return
* int** for assignment back in the caller. Avoids becoming a
* 3-Star Programmer (not a compliment). return NULL on failure.
*/
int **obtn_matrix (int *m, int *n)
{
fputs ("enter number of rows: ", stdout);
if (scanf ("%d", m) != 1) { /* validate ALL user-input */
fputs ("error: invalid number of rows.\n", stderr);
return NULL;
}
fputs ("enter number of cols: ", stdout);
if (scanf ("%d", n) != 1) {
fputs ("error: invalid number of cols.\n", stderr);
return NULL;
}
return create_matrix (*m, *n);
}
void prnt_matrix (int **matrix, int m, int n)
{
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++)
printf (" %4d", matrix[i][j]);
putchar ('\n');
}
}
void free_matrix (int **matrix, int m)
{
for (int i = 0; i < m; i++)
free (matrix[i]); /* free integers */
free (matrix); /* free pointers */
}
int main (void) {
int **matrix, m = 0, n = 0;
if ((matrix = obtn_matrix (&m, &n)) == NULL)
return 1;
prnt_matrix (matrix, m, n);
free_matrix (matrix, m);
return 0;
}
Since you "didn't share the filler function", the code above simply zeros all integer values by allocating the integers for each row with calloc instead of malloc which is a good idea when working with simulated arrays so that if you inadvertently fail to initialize one of the integers, you don't SegFault when you attempt to traverse all elements to, e.g. prnt_matrix, etc...
Example Use/Output
$ ./bin/matrix_cr_obtn
enter number of rows: 5
enter number of cols: 3
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
Memory Use/Error Check
In any code you write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.
It is imperative that you use a memory error checking program to insure you do not attempt to access memory or write beyond/outside the bounds of your allocated block, attempt to read or base a conditional jump on an uninitialized value, and finally, to confirm that you free all the memory you have allocated.
For Linux valgrind is the normal choice. There are similar memory checkers for every platform. They are all simple to use, just run your program through it.
$ valgrind ./bin/matrix_cr_obtn
==10251== Memcheck, a memory error detector
==10251== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==10251== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==10251== Command: ./bin/matrix_cr_obtn
==10251==
enter number of rows: 5
enter number of cols: 3
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
==10251==
==10251== HEAP SUMMARY:
==10251== in use at exit: 0 bytes in 0 blocks
==10251== total heap usage: 6 allocs, 6 frees, 100 bytes allocated
==10251==
==10251== All heap blocks were freed -- no leaks are possible
==10251==
==10251== For counts of detected and suppressed errors, rerun with: -v
==10251== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Always confirm that you have freed all memory you have allocated and that there are no memory errors.
Look things over and let me know if you have further questions.

Converting a 2D array into a dynamic array causes core dump

I have a perfectly working code with 2D array of a float variable, vxy, in C language. The size of row (rrow) is being calculated inside the code - column (ccol) size is already known. So I tried converting using code fragments in this forum and both causes segmentation fault. The two codes are i) Bryan's method from how to allocate memory dynamically for a two dimensional array and ii) Using pointer to a pointer method from http://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/. I chose these methods as the code is already functional with a 2D array so the rest of the code will survive this change.
static float vxy[5000][ccol] ;
vxy[r][c] = ...
The original 2D declaration and usage is above:
#include <stdlib.h>
int main(void)
{
int num_row = 3, num_col = 2, r;
int ** A;
A = malloc(num_row*(sizeof(*A)+num_col*sizeof(**A)));
for (r = 0; r < num_row; r++)
{
A[r] = (int*)(A+num_row)+r*num_col;
}
/* Accessing element at row r and column c is through:
*
* A[r][c].
*/
free(A);
return 0;
}
My implementation based on the above is:
int r;
float ** vxy;
vxy = malloc(rrow*(sizeof(*vxy)+ ccol*sizeof(**vxy)));
for (r = 0; r < rrow; r++) {
vxy[r] = (float*)(vxy + rrow) + r*ccol;
}
The second method is:
float **vxy = (float **)malloc(rrow * sizeof(float *));
for (i=0; i<rrow; i++)
vxy[i] = (float *)malloc(ccol * sizeof(float));
I updated the above 2nd method with the following - I got "Program received signal SIGSEGV, Segmentation fault" on the line of vxy[i] = malloc(ccol * sizeof(float));
float **vxy = malloc(rrow * sizeof(float *));
if (vxy = NULL) {
printf ("Memory allocation error.\n");
// return NULL;
}
for (i = 0; i < rrow; i++)
vxy[i] = malloc(ccol * sizeof(float));
What seems to going wrong with my implementation?
Update: I updated the full code from the source for the method one. I also want to know how to free the allocation and address failed malloc situations.
I'm sorry you are having difficulty with your 2D allocation, it really isn't too difficult. To dynamically allocate and access your elements with array[x][y] notation, you need to allocate x pointers to an array of float's (your rows), then allocate an y arrays of float's (your elements/columns) for each row. (no different than allocating an array of pointers to strings to hold lines of text)
An example of a simple allocation/initialization function with calloc (with m rows and n columns) shown without error checking on allocation is:
float **mtrx_calloc (size_t m, size_t n)
{
register size_t i;
float **array = calloc (m, sizeof *array);
for (i = 0; i < m; i++)
{
array [i] = calloc (n, sizeof **array);
}
return array;
}
To allocate a 3x4 matrix, you would use it like this:
float **matrix = mtrx_calloc (3, 4);
You can then manipulate the matrix as you like accessing all elements with matrix[x][y] notation. Also note the use of size_t instead of int. Your rows and columns and iterator will never be negative, so choosing size_t or unsigned type makes more sense.
Sometimes rather than looking at pieces of code, it is good to have a working example. I put together a short working example to help you along that includes all points we have discussed so far in the comments and above. It includes error checking on memory allocation omitted above. If you have any questions, just drop a comment.
#include <stdio.h>
#include <stdlib.h>
float **mtrx_calloc (size_t m, size_t n); /* initialize elements to 0 */
void mtrx_prn (size_t m, size_t n, float **matrix); /* print matrix with/pad */
void mtrx_free (size_t m, float **matrix); /* free memory allocated */
int main (void)
{
/* allocate the 3x4 matrix */
float **matrix = mtrx_calloc (3, 4);
/* fill with misc values */
register size_t i = 0, j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
matrix [i][j] = (float)(i + j);
}
/* print matrix */
printf ("\nThe dynamically allocated 3x4 matrix is:\n\n");
mtrx_prn (3, 4, matrix);
/* free memory alocated */
mtrx_free (3, matrix);
/* just to make it look pretty */
printf ("\n");
return 0;
}
/* allocate/initialize mxn matrix */
float **mtrx_calloc (size_t m, size_t n)
{
register size_t i;
float **array = calloc (m, sizeof *array);
if (!array) { /* validate allocation */
fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);
exit (EXIT_FAILURE);
}
for (i = 0; i < m; i++)
{
array[i] = calloc (n, sizeof **array);
if (!array[i]) { /* validate allocation */
fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);
exit (EXIT_FAILURE);
}
}
return array;
}
/* print a (m x n) matrix (check pad alloc) */
void mtrx_prn (size_t m, size_t n, float **matrix)
{
register size_t i, j;
for (i = 0; i < m; i++)
{
char *pad = "[ ";
for (j = 0; j < n; j++)
{
printf ("%s%6.3f", pad, matrix [i][j]);
pad = ", ";
}
printf ("%s", " ]\n");
}
}
void mtrx_free (size_t m, float **matrix)
{
register size_t i;
for (i = 0; i < m; i++)
{
free (matrix [i]);
}
free (matrix);
}
Output
(note: the fill with misc values equation was changed to prevent overflow on entry of large m x n, so output values will differ from below)
$ ./bin/mtrx_dyn_example
The dynamically allocated 3x4 matrix is:
[ 1.900, 2.800, 3.700, 4.600 ]
[ 2.800, 3.700, 4.600, 5.500 ]
[ 3.700, 4.600, 5.500, 6.400 ]
Leak Check with valgrind
When you are creating/allocating blocks of memory dynamically, you are responsible to tracking what you have allocated, preserving the starting address for the block of memory, and freeing the block of memory when you no longer need it. A great tool to help you check your memory use is a memory checker such as valgrind. (similar tools are available for all platforms). Simple to use, just valgrind ./progname. It will confirm for you whether any blocks remain unfreed and whether there are any access errors regarding your allocated blocks:
$ valgrind ./bin/mtrx_dyn_example
==15800== Memcheck, a memory error detector
==15800== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==15800== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==15800== Command: ./bin/mtrx_dyn_example
==15800==
The dynamically allocated 3x4 matrix is:
[ 1.900, 2.800, 3.700, 4.600 ]
[ 2.800, 3.700, 4.600, 5.500 ]
[ 3.700, 4.600, 5.500, 6.400 ]
==15800==
==15800== HEAP SUMMARY:
==15800== in use at exit: 0 bytes in 0 blocks
==15800== total heap usage: 4 allocs, 4 frees, 72 bytes allocated
==15800==
==15800== All heap blocks were freed -- no leaks are possible
==15800==
==15800== For counts of detected and suppressed errors, rerun with: -v
==15800== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
The problem is with the interplay between pointer to floats and actual floats, as mentioned in referenced answers, try to remove the type-casting and see what you get.
Both methods are valid (but accessed in different ways), there is also a first method which creates a 1-d array which represents a 2d array (thus accessed as a[i+j*r]), while the (first and) second methods actually allocates a 2-d array (accessed as a[i][j]).
try to use calloc as well if this helps, although malloc should be fine
Also try to fix your indices correctly (in the loops) when using either method to make sure you dont access memory out-of-bounds in the allocated array

Resources