C: Heap block at ### modified at ### past requested size of ### - c

So I'm storing a 2D dynamic Array into a matrix struct:
struct Matrix {
int ncol;
int nrow;
double **mat;
};
typedef struct Matrix Matrix;
I then have a function that takes the contents from a 2D array and stores it into the matrix:
// Initializes matrix mat whose values are the passed in 2D array
// Made Matrix **mat a double pointer so that I can initialize the Matrix *pointer from Main
void matrix_initializeFromArray(Matrix **mat, int nrow, int ncol, double array[][ncol]) {
(*mat) = (Matrix*) malloc(sizeof(Matrix*));
(*mat)->mat = (double**) malloc(nrow*sizeof(double*));
for(int i = 0; i < nrow; i++) {
(*mat)->mat[i] = (double*) malloc(ncol*sizeof(double*));
for(int j = 0; j < ncol; j++) { // intialize all values to array values
(*mat)->mat[i][j] = array[i][j];
}
}
(*mat)->ncol = ncol;
(*mat)->nrow = nrow;
}
Where this is the destructor for the matrix:
// Destructor
void matrix_destructor(Matrix **mat) {
for(int i = 0; i < (*mat)->nrow; i++) {
free((*mat)->mat[i]);
}
free((*mat)->mat);
free(*mat);
}
A small example of this is the following:
void main() {
Matrix *temp;
double array[1][1];
array[0][0] = 34;
matrix_initializeFromArray(&temp, 1, 1, array);
matrix_print(temp);
matrix_destructor(&temp);
}
This code executes normally on gdb and valgrind in my Linux Ubuntu but for some reason it creates this error while I run it on Windows.
warning: HEAP[a.exe]:
warning: Heap block at 00B51710 modified at 00B5171C past requested size of 4
I ran through the gdb on Windows and it occurs at this line in the destructor on the first loop: free((*mat)->mat[i]);
Any Help?

I have simplified your code, matrix_print is missing
The issue was with the malloc
when you allocate something you get a pointer to the memory, for example
malloc(sizeof(double)); returns a pointer to a memory area that can store a double so a double *
malloc(sizeof(double*)); returns a pointer to a memory are that can store a pointer to a double, so a double **`
#include <stdio.h>
#include <stdlib.h>
struct Matrix {
int ncol;
int nrow;
double **mat;
};
typedef struct Matrix Matrix;
void matrix_initializeFromArray(Matrix *mat, int nrow, int ncol, double array[][ncol]) {
mat->ncol = ncol;
mat->nrow = nrow;
mat->mat = malloc(nrow * sizeof(double*));
for(int i = 0; i < nrow; i++) {
mat->mat[i] = malloc(ncol*sizeof(double));
for(int j = 0; j < ncol; j++) { // intialize all values to array values
mat->mat[i][j] = array[i][j];
}
}
}
void matrix_wipe(Matrix *mat) {
for(int i = 0; i < mat->nrow; i++) {
free(mat->mat[i]);
}
free(mat->mat);
}
int main(void) {
Matrix temp;
double array[1][1];
array[0][0] = 34;
matrix_initializeFromArray(&temp, 1, 1, array);
matrix_wipe(&temp);
return 0;
}

Related

Returning from a function with incompatible return type int **

I have an exam and the teacher want to do a problem. It sound like this.
a)Reading information about an array (the function returns a structure associated with an array)
b)Reading the elements of an array (the function receives as parameters two integers and a pointer to FILE and returns a pointer to pointer to integer)
the point a) is Matrix* infoM.
the point b) is int** readM
And I get an error with the returning type
enter code here
#include <stdio.h>
#include <stdlib.h>
typedef struct Matrix{
int rows;
int cols;
int** data;
}Matrix;
Matrix* infoM( int n_rows, int n_cols)
{Matrix Matrix;
int i;
Matrix.rows = n_rows;
Matrix.cols = n_cols;
Matrix.data = (int**)malloc(sizeof(int*) * n_rows);
if(Matrix.data == 0)
{
fprintf(stderr, "err");
exit(EXIT_FAILURE);
}
for(i=0;i<n_rows;i++)
{
*(Matrix.data+i) = (int*)malloc(sizeof(int)*n_cols);
if(*(Matrix.data+i) == 0)
{
fprintf(stderr,"err");
exit(EXIT_FAILURE);
}
}
struct Matrix *m;
m = &Matrix;
return m;
}
int** readM(int n_rows, int n_cols, FILE *in)
{
Matrix* matrix = infoM(n_rows,n_cols);
int i,j;
for(i=0; i<n_rows; i++)
{
for(j=0; j<n_cols; j++)
{
fscanf(in, "%d",*(matrix->data+i)+j);
}
}
return matrix;
}
I would use a flexible array member to remove double-pointer - and additional overhead (it removes one level of indirection). Additionally, it simplifies malloc/free (only one needed).
To access data use an array pointer.
typedef struct Matrix{
size_t rows;
size_t cols;
int data[];
}Matrix;
Matrix *createM(size_t rows, size_t cols)
{
Matrix *m = malloc(sizeof(*m) + cols * rows * sizeof(m -> data[0]));
return m;
}
Matrix *initM(Matrix *m)
{
int (*data)[m -> cols] = (int (*)[m -> cols])m -> data;
for(size_t row = 0; row < m -> rows; row++)
{
for(size_t col = 0; col < m -> cols; col++)
{
data[row][col] = rand();
}
}
return m;
}
Use correct types for sizes.
C has a notion of lifetime for variables. Automatic variables (declared in a block of function) reach their end of life at the end of the block (or function...) where they are declared in. And using an object passed its end of life explicetely invokes Undefined Behaviour (close to hell for C programmers).
For that reason you cannot return the address of a local variable. It is called a dangling pointer (Google that word for additional details...).
But C allows to return a whole structure. So a minimal modification of your code could be:
...
Matrix infoM( int n_rows, int n_cols)
{Matrix Matrix;
int i;
Matrix.rows = n_rows;
...
return Matrix;
}
Matrix readM(int n_rows, int n_cols, FILE* in)
{
Matrix matrix = infoM(n_rows, n_cols);
int i, j;
for (i = 0; i < n_rows; i++)
{
for (j = 0; j < n_cols; j++)
{
fscanf(in, "%d", matrix.data[i] + j); // more C idiomatic...
}
}
return matrix;
}
For the same reason, readM is not allowed to return a pointer inside a local object, because it would be a dangling pointer, but you can again return the struct itself.

Dynamically allocating a 3D matrix in C

So I've got a 2D Array which I am creating like this:
int** init_grid(int cell_grid_size) {
// matrix variables
int *memory_grid;
int **matrix;
int i;
int j;
// memory for matrix
memory_grid = malloc(cell_grid_size * cell_grid_size * sizeof(int));
matrix = malloc(cell_grid_size * sizeof(int *));
// fill matrix with rows
for(i = 0; i < cell_grid_size; i++) {
matrix[i] = &memory_grid[i*cell_grid_size];
}
// return fresh matrix
return matrix;
}
As you can see it's initialising a matrix of integers. However, I'd like to to initialize a matrix of integer arrays of size 2 (ie a 3D Matrix) but I can't quite seem to get my head around how to add the next dimension.
Any help would be greatly appreciated.
void grid_init(int* matrix, unsigned int xsize, unsigned int ysize, unsigned int unsigned int zsize)
{
unsigned int matrix_size;
// flatten matrix size in Byte
matrix_size = xsize*ysize*zsize*sizeof(int);
matrix = (int*)malloc(matrix_size);
memset(matrix, 0, sizeof(matrix_size);
}
Once matrix is built, you can loop through it using that loop:
void grid_fill(int* matrix, int value, unsigned int xsize, unsigned int ysize, unsigned int zsize)
{
int i,j,k;
for(k=0; k<zsize; k++)
{
for(i=0; i<ysize; i++)
{
for(j=0; j<xsize; j++)
{
matrix[j+i*xsize+k*ysize*xsize] = value;
}
}
}
}
For an int *** pointing to an array of pointers of type int **. Each pointing to an int *. Each int * pointer to an array of int.
Allocation checks for NULL omitted for brevity.
int*** init_grid(size_t xsize, size_t ysize, size_t zsize) {
int ***matrix = malloc(sizeof matrix[0] * xsize);
for (x = 0; x < xsize; x++) {
matrix[x] = malloc(sizeof matrix[x][0] * ysize);
for (y = 0; y < ysize; y++) {
matrix[x][y] = malloc(sizeof matrix[x][y][0] * zsize);
// or to zero-out the `int` data
matrix[x][y] = calloc(zsize, sizeof matrix[x][y][0]);
}
}
return matrix;
}
Use size_t for array indexing and sizing.
To free:
void free_grid(int ***matrix, size_t xsize, size_t ysize) {
if (matrix) {
for (x = 0; x < xsize; x++) {
if (matrix[x]) {
for (y = 0; y < ysize; y++) {
free(matrix[x][y])
}
}
free(matrix[x]);
}
free(matrix);
}
}

C - address of matrix as an argument in function

I have this header:
#define SIZE 4
typedef float matrix[SIZE][SIZE];
typedef struct {
char *name;
matrix *mat;
} matRec;
void printMat(matrix *);
void read_mat(matrix , float []);
declaration in the main:
matrix m[6];
matRec mats[6] = {
{"MAT_A", &m[0]},
{"MAT_B", &m[1]},
{"MAT_C", &m[2]},
{"MAT_D", &m[3]},
{"MAT_E", &m[4]},
{"MAT_F", &m[5]}
};
struct {
char *name;
void (*func)();
} cmd[] = {
{"read_mat", read_mat},
{"not_valid", NULL}
};
this is also part of my main:
(*(cmd[func].func))(&mats[matrixx].mat, num);
printMat(mats[matrixx].mat);
my printMat function in the main:
void printMat(matrix *matrx) {
int i,j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
printf("%7f ", matrx[i][j]);
}
printf("\n");
}
printf("\n");
}
and the read_mat function (in another file):
void read_mat(matrix matrx, float num[]) {
int i, j, count = 0;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
matrx[i][j] = num[count];
count++;
}
}
}
My purpose is to send an address of my matrix from array: mats, with array of float numbers, insert them, and print the matrix with another function. I have difficulties in sending the address. The read_mat function does "work", but with a copy of matrix(in the scope of the function), then obviously prints matrix with only zeros. I don't understand how to write the right types of arguments with pointers in declaration of function. Any other combination of * gives error. THANKS
I guess few of the type information would help you. Here by saying this
matrix m[6];
You are basically declaring
float m[6][SIZE][SIZE];
And then type of m[0] is nothing but float [SIZE][SIZE] or matrix.
So when I pass it's address to a function it would be
somefun(&m[0]);
You would declare and use it like this
..somefun(matrix *t){
for(int i = 0; i< SIZE; i++)
for(int j =0 ; j< SIZE; j++)
printf("%lf",(*t)[i][j]);
..
}

Freeing dynamically allocated matrix

I have this code for allocating a float matrix on runtime:
float **create_matrix(int w, int h) {
// alocates the matrix rows first
float **matrix = (float**)malloc(h * sizeof(float*));
// now allocates and populates each line
for (int i = 0; i < h; i++) {
matrix[i] = (float*) malloc(w * sizeof(float));
// sample matrix filling
for (int j = 0; j < w; j++)
matrix[i][j] = (i + 1) * (j + 1);
}
return matrix;
}
It seems to be working fine, since it doesn't crash and when I display the matrix I have the very same values that I initialized it. Although when I try to free the matrix, iff the number of rows is lesser than the number of columns, I receive the following error message:
a.out(14284,0x7fff73cc9300) malloc: * error for object 0x9000000000000000: pointer being freed was not allocated
* set a breakpoint in malloc_error_break to debug. Abort trap: 6"
My freeing routine follows:
void free_matrix(float **matrix, int h) {
for (int i = 0; i < h; i++)
free(matrix[i]);
free(matrix);
}
Try this
#include <stdio.h>
#include <stdlib.h>
float **create_matrix(int h, int w)
{
float **matrix = (float **)malloc(h*sizeof(float *));
int i,j;
for(i=0;i<h;i++){
matrix[i] = (float *)malloc(w*sizeof(float));
}
for(i=0;i<h;i++){
for(j=0;j<w;j++){
matrix[i][j] = (i+1)*(j+1);
}
}
return matrix;
}
int main()
{
int h = 2, w = 3;
float **matrix = create_matrix(h,w);
int i,j;
for(i=0;i<h;i++){
for(j=0;j<w;j++){
printf("%.2f ",matrix[i][j]);
}
printf("\n");
}
return 0;
}
You need to allocate memory before you start making operations.

return a fixed size array in c

I would like a function to return an array, or a pointer to an array, in either c or c++, that does something like the following:
double[][] copy(double b[][], int mx, int my, int nx, int ny)
{
double[nx][ny] a;
int i,j;
for(i = mx; i<= nx; ++i)
for(j = my; j<= ny; ++j)
a[i][j] = b[i][j];
return a;
}
void main(void){
double A[2][3];
double B[2][3] = {{1,2}{3,4}{5,6}};
A = copy(B,0,0,1,2);
}
This is the proper method for returning an array from a function is as follows:
#define NUM_ROWS (5)
#define NUM_COLS (3)
char **createCharArray(void)
{
char **charArray = malloc(NUM_ROWS * sizeof(*charArray));
for(int row = 0; row < NUM_ROWS; row++)
charArray[row] = malloc(NUM_COLS * sizeof(**charArray));
return charArray;
}
In this example, the above function can be called like this:
char **newCharArray = createCharArray();
newCharArray can now be used:
char ch = 'a';
for(int row = 0; row < NUM_ROWS; row++)
for(int col = 0; col < NUM_COLS; col++)
newCharArray[row][col] = ch++;
An array can be passed as an argument to function similarly:
void freeCharArray(char **charArr)
{
for(int row = 0; row < NUM_ROWS; row++)
free(charArr[row]);
free(charArr);
}
You can return the double ** from your copy function like this.
double ** copy(double *src, int row, int col)
{
// first allocate the array with required size
double **copiedArr = (double **) malloc(sizeof(double *)*row);
for(int i=0;i<row;i++)
{
// create space for the inner array
*(copiedArr+i) = (double *) malloc(sizeof(double)*col);
for(int j=0; j<col; j++)
{
// copy the values from source to destination.
*(*(copiedArr+i)+j) = (*(src+i+j));
}
}
// return the newly allocated array.
return copiedArr;
}
call to this function is done like this.
double src[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
double **dest = copy(&src[0][0],3,3); //here is your new array
Here you have to assign returned value of copy() to double** not to double[][].
If you try to assign the returned value to array then it will generate "Incompatible types" error (detail).
As memory allocated to copiedArray on the heap so you have to take responsibility to clear the memory.
void freemem(double **mem, int row)
{
for(int i=0;i<row; i++)
{
free(*(mem+i));
}
free(mem);
}
I also want to point out some correction in your sample code:
return type of main should be int.
one should put the return statement at the end of main.
you can't return the stack allocated value, it is cause of crash
in most of cases.

Resources