Dynamically allocating and _freeing_ two-dimensional double array - c

Here's my code:
#include <stdio.h>
#include <stdlib.h>
#define M 5
#define N 3
double **create_matrix(int m, int n);
void destroy_matrix(double **matrix, int m);
int main(void)
{
int i = 0, j = 0;
int x = 0;
double **matrix;
matrix = create_matrix(M, N);
while (i < M) {
j = 0;
while (j < N) {
printf("%4.0f", *(*(matrix + j) + i) = j);
j++;
}
putchar('\n');
i++;
}
destroy_matrix(matrix, M);
return 0;
}
double **create_matrix(int m, int n)
{
int i = 0;
double **matrix;
if ((matrix = (double **) malloc(sizeof(double *) * m)) != NULL) {
while (i < m)
if ((*(matrix + i++) = (double *) malloc(sizeof(double) * n)) == NULL)
return NULL;
return matrix;
} else
return NULL;
}
void destroy_matrix(double **matrix, int m)
{
int i = 0;
while (i < m)
free((void *) *(matrix + i++));
free((void *) matrix);
}
Allocating, initializing and printing the matrix works.
Allocating, not initializing and freeing works.
Allocating, initializing AND freeing does NOT work.
Backtrace:
*** glibc detected *** [file]: free(): invalid next size (fast): 0x0000000001e7d040 ***
Followed by a memory map.
I searched for similar problems but couldn't find one fitting my situation, nor could I derive mine from them.

Your matrix allocation and deallocation functions look fine to me.
But the initialization of the matrix elements has an error:
while (i < M) {
j = 0;
while (j < N) {
printf("%4.0f", *(*(matrix + j) + i) = j);
j++;
}
putchar('\n');
i++;
}
This expression
*(*(matrix + j) + i)
has to be changed by this expression
*(*(matrix + i) + j)
because i are your rows and j are your columns.
Note that you could also use the simpler form matrix[i][j] which is equivalent to *(*(matrix + i) + j) in your program.

You are freeing the dereference, i.e. the address pointed to by the contents of the array. Try this instead. Note the lack of '*' before '(matrix + i++) on line 6
void destroy_matrix(double **matrix, int m)
{
int i = 0;
while (i < m)
free((void *) (matrix + i++));
free((void *) matrix);
}

Related

I'm not able to read my matrix dynamically

My program crashes when it comes to the reading function, at the scanf line. What can I do?
I'm guessing it's an issue with the way I wrote (*(a + i) + j) but I can't tell.
void read(int **a, int n)
{
int i, j;
for(i=0;i<n;i++)
for (j = 0; j < n; j++)
{
printf("a[%d][%d]=", i, j);
scanf("%d", (*(a + i) + j)); //Access violation writing location
}
}
void show(int**a, int n)
{
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
{
printf("%d", *(*(a + i) + j));
}
}
int main()
{
int n,opt,a;
printf("number of lines and columns:");
scanf("%d", &n);
a = (int**)malloc(n*n * sizeof(int));
while (1)
{...
A dynamic 2D n x n array is allocated using this code:
int (*a)[n] = malloc(n * sizeof *a);
It means: Declare a as pointer to an integer array with n element and allocate n of those arrays (i.e. n * sizeof *a). In that way it ends up with n x n integers.
So a full version of your code could be like:
#include <stdio.h>
#include <stdlib.h>
void read(int n, int a[][n])
{
int i, j;
for(i=0;i<n;i++)
for (j = 0; j < n; j++)
{
printf("a[%d][%d]=\n", i, j);
scanf("%d", &a[i][j]);
}
}
void show(int n, int a[][n])
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
printf("%d ", a[i][j]);
}
puts("");
}
}
int main(void)
{
int n = 0;
printf("number of lines and columns:\n");
scanf("%d", &n);
if (n < 1) exit(1);
int (*a)[n] = malloc(n * sizeof *a);
read(n, a);
show(n, a);
free(a);
return 0;
}
note : To keep it simple I skipped all check of scanf return values. In real code, the scanf return value shall always be checked.
There is nothing wrong with allocating a block using malloc ( n * n * sizeof *a);
The address of the block must be assigned to a pointer int *a
Elements can be accessed by (a + i * n + j) or a[i * n +j]
void read(int *a, int n)
{
int i, j;
for(i=0;i<n;i++)
for (j = 0; j < n; j++)
{
printf("a[%d][%d]=", i, j);
scanf("%d", (a + i * n + j));
// scanf("%d", &a[i * n + j]);
}
}
void show(int *a, int n)
{
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
{
printf("%d", *(a + i * n + j));
// printf("%d", a[i * n + j]);
}
}
int main()
{
int n = 0, opt = 0, *a = NULL;
printf("number of lines and columns:");
scanf("%d", &n);
a = malloc ( n * n * sizeof *a);
while (1)
{...

Difference between malloc and calloc in this case?

This is a code for multiplying two square matrices in C.
What is the difference between using malloc and calloc in void multiply() function?
When using malloc, I am getting garbage values, but calloc is providing the right answer.
Only the first row is outputting garbage values so is it an issue with the way malloc allocates space in the heap as compared to calloc?
#include <stdio.h>
#include <stdlib.h>
int *getArray(int);
void display(int *, int, int);
void multiply(int *, int *, int);
int main() {
int n;
printf("enter dimension of square matrix:\n");
scanf("%d", &n);
int *arr1;
int *arr2;
arr1 = getArray(n);
display(arr1, n, n);
printf("\n now give input for next array");
arr2 = getArray(n);
display(arr2, n, n);
printf("\n\n\n");
multiply(arr1, arr2, n);
return 0;
}
int *getArray(int n) {
int *arr = (int *)malloc(n * n * sizeof(int));
printf("\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", (arr + i * n + j));
}
}
/*for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf(" %d ", *(arr + i * n + j));
}
printf("\n");
}*/
return arr;
}
void display(int *arr, int row, int col) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
printf(" %d ", *(arr + i * row + j));
}
printf("\n");
}
}
void multiply(int *arr1, int *arr2, int n) {
int *arr = (int *)calloc(n * n, sizeof(int));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
*(arr + i * n + j) += (*(arr1 + i * n + k)) * (*(arr2 + k * n + j));
}
}
}
printf("product of above matrices = \n\n");
display(arr, n, n);
}
The only functional difference between allocating memory with malloc() and with calloc() for the same size, assuming the size computation is accurate, is the latter initializes the block to all bits 0, whereas the former does not.
All bits 0 means all int values in the array are initialized to 0.
The inner loop in the multiply function only increments the element at row i and column j, therefore the function relies on implicit initialization of the array elements to 0. calloc() does that, but not malloc() so you definitely need to use calloc().
Also note these remarks:
in display the computation for the offset of the matrix element at row i column j should be printf(" %5d ", *(arr + i * col + j));
multiply should return arr and display() should be called in the main function.
you should check for scanf(), malloc() and calloc()` failure
you should free allocated memory
pointer arguments to objects that are not modified by the function should be const qualified so the function can be called with a pointer to a const object.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int *getArray(int);
void display(const int *, int, int);
int *multiply(const int *, const int *, int);
int main() {
int n;
printf("enter dimension of square matrix:\n");
if (scanf("%d", &n) != 1)
return 1;
printf("\n now give input for the first array");
int *arr1 = getArray(n);
if (!arr1)
return 1;
display(arr1, n, n);
printf("\n now give input for the second array");
int *arr2 = getArray(n);
if (!arr2)
return 1;
display(arr2, n, n);
printf("\n\n\n");
int *arr = multiply(arr1, arr2, n);
if (!arr)
return 1;
printf("product of above matrices = \n\n");
display(arr, n, n);
free(arr1);
free(arr2);
free(arr);
return 0;
}
int *getArray(int n) {
int *arr = malloc(sizeof(int) * n * n);
if (arr == NULL)
return NULL;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (scanf("%d", (arr + i * n + j)) != 1) {
free(arr);
return NULL;
}
}
}
return arr;
}
void display(const int *arr, int row, int col) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
printf(" %5d ", *(arr + i * col + j));
}
printf("\n");
}
}
int *multiply(const int *arr1, const int *arr2, int n) {
int *arr = calloc((size_t)n * n, sizeof(int));
if (arr == NULL)
return NULL;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
*(arr + i * n + j) += (*(arr1 + i * n + k)) * (*(arr2 + k * n + j));
}
}
}
return arr;
}

Function to transpose a matrix in place

I have written the following function in C
double * transpose(double *M, int n) {
double *T = (double *) malloc(n * n * sizeof(double));
int i, j;
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
T[i + (j * n)] = M[(i * n) + j];
}
}
return T;
}
and I call it as such:
C = transpose(C, n);
where C was previously declared as
double *C = (double *) malloc(n * n * sizeof(double));
and then initialised with values.
How can I, instead of returning T, set my function type to void and then call the equivalent of *M = *T instead of my return statement. In other words, how can I call the function like:
transpose(C, n);
so that *C is pointing to the memory allocation created by *T?
EDIT:
As pointed out by wildplasser below, a more efficient way of transposing the matrix in place would be swapping the {i, j} pairs except along the diagonal.
Something along the lines of this:
void * transpose(double *M, int n) {
int i, j;
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
if (i != j) {
double temp = M[i + (j * n)];
M[i + (j * n)] = M[(i * n) + j];
M[(i * n) + j] = temp;
}
}
}
}
However, calling this as
transpose(C, n);
does not allow C to keep it's transposition after the function. What am I doing wrong here?
Also GCC is giving me the warning
Utilities.c: In function 'transpose':
Utilities.c:34:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
I have defined my function as void in both the header and source file?
void transpose(double *arr, size_t siz)
{
size_t ii,jj;
for(ii=0;ii<siz;ii++) {
for(jj=ii+1;jj<siz;jj++){
double tmp;
size_t aa,bb;
aa = ii+ siz * jj;
bb = jj+ siz * ii;
tmp = arr[aa];
arr[aa] = arr[bb];
arr[bb] = tmp;
}
}
}
Don't worry about theaa and bb variables. Any decent compiler will optimize them away.
First of all, your code has a memory leak. You overwrite the previous value of C without ever freeing it.
To transpose in place, you need to just swap all the right indexes without swapping twice. So it's like the same problem as reversing an array in place.
void transpose(double *M, int n) {
int i, j;
double temp;
for(i = 0; i < n; i++) {
for(j = 0; j < i; j++) {
temp = M[i + j * n];
M[i + j * n] = M[j + i * n];
M[j + i * n] = temp;
}
}
}
void transpose(double **C, double *M, int n) {
double *T = (double *) malloc(n * n * sizeof(double));
int i, j;
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
T[i + (j * n)] = M[(i * n) + j];
}
}
*C = T;
}
And call your function like this :
transpose(&C, n);
As the comments suggest free the old C before to avoid memory leak

Transpose a matrix via pointer in C

I'm trying to transpose a matrix in C while passing the matrix to a function and return a pointer to a transposed matrix. What am I doing wrong in the second while loop?
in main
ptr = (float *) getMatrix(numRowsB, numColsB);
transposePtr = transpose(ptr, numRowsB, numColsB);
printf("\nBtranspose =\n");
printMatrix(transposePtr, numColsB, numRowsB);
create matrix
float* getMatrix(int n, int m)
{
int i, j;
float *arrayPtr;
if ((n <= 0) || (m <= 0))
{
printf("function getMatrix(): matrix dimensions are invalid\n");
return NULL;
}
arrayPtr = (float *) malloc(n*m*sizeof(float));
if(arrayPtr == NULL)
{
printf("function getMatrix: Unable to malloc array\n");
return NULL;
}
transpose function
float* transpose(float *matrix, int n, int m)
{
int i = 0;
int j = 0;
float num;
float *transposed=(int*) malloc(sizeof(int)*n*m);
while(i < n-1)
{
while(j < m-1)
{
num = *(matrix+i*m+j);
*(transposed+j*m+i)= num;
j++;
}
i++;
}
return transposed;
}
print fucntion
void print(float *matrix, int n, int m)
{
int i = 0;//row counter
int j = 0;//col counter
for(i = 0; i < n; i++){
printf("\n");
for(j = 0; j < m; j++){
printf("%f ", *(matrix + i*n + j));
}
}
}
Example input:
1 2 3
4 5 6
Output:
1.000000 0.000000
2.000000 3396.580087
-0.000000 0.000000
Part of the problem was your print function
Here is a version of your functions that works:
float* transpose(float *matrix, int n, int m)
{
int i = 0;
int j = 0;
float num;
float *transposed=malloc(sizeof(float)*n*m);
while(i < n) {
j = 0;
while(j < m) {
num = *(matrix + i*m + j);
*(transposed + i+n*j) = num; // I changed how you index the transpose
j++;
}
i++;
}
return transposed;
}
void print(float *matrix, int n, int m)
{
int i = 0;//row counter
int j = 0;//col counter
for(i = 0; i < n; i++){
printf("\n");
for(j = 0; j < m; j++){
printf("%f ", *(matrix + i*m + j)); // Changed from n to m
}
}
}
There were a few things.
Use sizeof(float) instead of sizeof(int)
Your loop should be i < n and j < m instead of i < n-1 and j < m-1 and finally you need to reset j to zero every time
The matrix indexes in inner most loop of your transpose function was incorrect
Your print function was using the wrong variable in the multiplication
Also it is generally considered bad practice to cast the result of malloc in C.

How does the merge() in merge_sort() work?

So I was looking at the C example of merge sort on Rosetta Code and I'm a bit confused about how the merge() function works. I think it is the syntax they use that throws me off with the colons and ?'s.
void merge (int *a, int n, int m) {
int i, j, k;
int *x = malloc(n * sizeof (int));
for (i = 0, j = m, k = 0; k < n; k++) {
x[k] = j == n ? a[i++]
: i == m ? a[j++]
: a[j] < a[i] ? a[j++]
: a[i++];
}
for (i = 0; i < n; i++) {
a[i] = x[i];
}
free(x);
}
void merge_sort (int *a, int n) {
if (n < 2)
return;
int m = n / 2;
merge_sort(a, m);
merge_sort(a + m, n - m);
merge(a, n, m);
}
What exactly is happening in the for loop of the merge() function? Can someone explain it please?
Read the comments:
void merge (int *a, int n, int m) {
int i, j, k;
// inefficient: allocating a temporary array with malloc
// once per merge phase!
int *x = malloc(n * sizeof (int));
// merging left and right halfs of a into temporary array x
for (i = 0, j = m, k = 0; k < n; k++) {
x[k] = j == n ? a[i++] // right half exhausted, take from left
: i == m ? a[j++] // left half exhausted, take from right
: a[j] < a[i] ? a[j++] // right element smaller, take that
: a[i++]; // otherwise take left element
}
// copy temporary array back to original array.
for (i = 0; i < n; i++) {
a[i] = x[i];
}
free(x); // free temporary array
}
void merge_sort (int *a, int n) {
if (n < 2)
return;
int m = n / 2;
// inefficient: should not recurse if n == 2
// recurse to sort left half
merge_sort(a, m);
// recurse to sort right half
merge_sort(a + m, n - m);
// merge left half and right half in place (via temp array)
merge(a, n, m);
}
A simpler and more efficient version of the merge function, using only half as much temporary space:
static void merge(int *a, int n, int m) {
int i, j, k;
int *x = malloc(m * sizeof (int));
// copy left half to temporary array
for (i = 0; i < m; i++) {
x[i] = a[i];
}
// merge left and right half
for (i = 0, j = m, k = 0; i < m && j < n; k++) {
a[k] = a[j] < x[i] ? a[j++] : x[i++];
}
// finish copying left half
while (i < m) {
a[k++] = x[i++];
}
}
A faster version of merge_sort involves allocating a temporary array x of size n * sizeof(*a) and passing it to a recursive function merge_sort1 that calls merge with as extra parameter as well. The logic in merge is also improved here with half as many comparisons on i and j:
static void merge(int *a, int n, int m, int *x) {
int i, j, k;
for (i = 0; i < m; i++) {
x[i] = a[i];
}
for (i = 0, j = m, k = 0;;) {
if (a[j] < x[i]) {
a[k++] = a[j++];
if (j >= n) break;
} else {
a[k++] = x[i++];
if (i >= m) return;
}
}
while (i < m) {
a[k++] = x[i++];
}
}
static void merge_sort1(int *a, int n, int *x) {
if (n >= 2) {
int m = n / 2;
if (n > 2) {
merge_sort1(a, m, x);
merge_sort1(a + m, n - m, x);
}
merge(a, n, m, x);
}
}
void merge_sort(int *a, int n) {
if (n < 2)
return;
int *x = malloc(n / 2 * sizeof (int));
merge_sort1(a, n, x);
free(x);
}

Resources