Matrix memory allocation through a function - c

I am using these lines to create variable size matrices:
Temp_Mat_0 = (double **)malloc((M)*sizeof(double ));
for (i=0;i<M;i++)
Temp_Mat_0[i] = (double *)malloc((N)*sizeof(double ));
They are working fine but I keep using them repeatedly in my code. I need to convert them to a function where I pass the pointer and the size. I was not able to do it due to pointers mess.
matrixAllocate(Matrix Pointer,rows,colms)
Can you help!

I think you'd be better off with a very simple scheme that allocates your matrix as a single contiguous block.
double **matrix_alloc(int rows, int cols)
{
/* Allocate array of row pointers */
double ** m = malloc(rows * sizeof(double*));
if (!m) return NULL;
/* Allocate block for data */
m[0] = malloc(rows * cols * sizeof(double));
if (!m[0]) {
free(m);
return NULL;
}
/* Assign row pointers */
for(int r = 1; r < rows; r++) {
m[r] = m[r-1]+cols;
}
return m;
}
This has the added bonus that when you free the matrix you don't need to remember how big it was:
matrix_free( double** m )
{
if (m) free(m[0]);
free(m);
}
As an extension to this, you might declare a struct that also keeps track of the number of rows and columns it has. e.g.
struct matrix {
int rows, cols;
double **m;
};
That makes your matrix functions look a little nicer (i.e. you can pass around struct matrix* instead of double**). It has the added bonus that the matrix dimension travels around with the associated data.
Using one contiguous block for your matrix data is generally preferable unless you have huge matrices. And it's very nice if your matrices are small, because you'll get the benefit of better memory locality in your CPU cache -- that means potential for faster code.

they are working fine
They do not seem really fine. Code should be changed to :
Temp_Mat_0 = malloc((M)*sizeof(double*)); //double* instead of double
if (Temp_Mat_0 == NULL)
return;
for (i = 0; i < M; i++){
Temp_Mat_0[i] = malloc((N)*sizeof(double));
if (Temp_Mat_0[i] == NULL){
free(Temp_Mat_0);
return;
}
}
Then, you can use a function like this :
double ** matrix_pointer = matrixAllocate(rows,colms);
where function matrixAllocate returns the pointer it allocated. For example :
matrixAllocate(rows,colms){
Temp_Mat_0 = malloc((rows)*sizeof(double*));
if (Temp_Mat_0 == NULL)
return NULL;
for (i = 0; i < rows; i++){
Temp_Mat_0[i] = malloc((colms)*sizeof(double));
if (Temp_Mat_0[i] == NULL){
free(Temp_Mat_0);
return NULL;
}
}
return Temp_Mat_0;
}
and call it like :
double **matrix pointer;
matrix pointer = matrixAllocate(rows, colms);
Don't forget to free the malloced memory afterwards.
for (i = 0; i < M; i++){
free(Temp_Mat_0[i]);
}
free(Temp_Mat_0);
Note that you should not cast the result of malloc, and you should also check if malloc was successful.

Related

Error with freeing memory in C, visual studio

I am working on a project that I have made use of Calloc and I am trying to free the memory at the end of my main{} function. However, after the program finishes running and I click on the stop, I get this "proj.exe has triggered a breakpoint."
at this set of codes:
while (freeSpace != NULL) {
free(freeSpace++);
}
Here are my codes for allocating memory:
scanf("%d", &SEG);
BLOCKS = 128 / SEG;
for (int k = 0; k < BLOCKS; k++)
{
memory = (int *)calloc(BLOCKS, sizeof(int));
// handle memory allocation failure
}
for (int i = 0; i < BLOCKS; i++)
{
memory[i] = (int *)calloc(SEG, sizeof(int));
// handle memory allocation failure
}
for (int l = 0; l < BLOCKS+5; l++)
{
//freeSpace = (int*)malloc(l * sizeof(int));
freeSpace = (int *)calloc( BLOCKS + 5, sizeof(int));
// handle memory allocation failure
}
for (int o = 0; o < BLOCKS; o++)
{
memorySpace = (int *)calloc(BLOCKS, sizeof(int));
// handle memory allocation failure
}
`
This is the part where I free my memory:
while (freeSpace != NULL) {
free(freeSpace++);
}
Can someone please assist me?
Its really hard to fix your issue because it seems like that these are only a part of your code or it is a prototype?
The following code only based on some 'guess':
int main()
{
scanf("%d", &SEG);
BLOCKS = 128 / SEG;
int* memory = (int *)calloc(BLOCKS+1, sizeof(int*)); // the last is a 'NULL' pointer
memset(memory, 0, sizeof(int*)*BLOCKS+1);
for (int i = 0; i < BLOCKS; i++)
{
memory[i] = (int *)calloc(SEG, sizeof(int));
// handle memory allocation failure
}
while (memory != NULL) {
free(memory++);
}
}
I think you are misunderstanding how pointers work when allocating arrays. Your very first loop has a memory leak in it because you are changing what I am assuming the "memory" pointer is pointing to.
To allocate an array in C would be like below.
int *bigspace;
bigspace = malloc(20 * sizeof(int));
Here we made the pointer "bigspace" point to a new chunk of memory 20 times the size of an integer which is an array. If you did something like below..
int *bigspace;
bigspace = malloc(20 * sizeof(int));
bigspace = malloc(20 * sizeof(int));
This would be no bueno. We are first making "bigspace" pointer point to a chunk of memory (array of ints) and then we are changing what "bigspace" is pointing to by making it point to a new chunk of memory. This means your first chunk of memory does not have a pointer to it anymore and that memory is leaked!
I think the problem is that the value of freeSpace++ is garbage at the end of your allocated memory.
Free a garbage pointer causes the problem.

Memory leaking in C, malloc inside function

I am trying to create a 2d array of struct grid_t, and am getting memory leak warnings via address sanitiser, and eventually a seg fault in certain conditions.
There may be various points in my code causing this, but I thought knowing what was going wrong here would point me in the right direction to fixing the rest.
I am new to C and thus to memory management, so all feedback is welcome and appreciated!
void createGridArray(atom_t* ATOM) {
ATOM -> grid = (grid_t**) malloc(WIDTH * sizeof(grid_t*));
grid_t *nullGrid = malloc(sizeof(grid_t));
grid_t temp = {NULL, 0};
*nullGrid = temp;
for (int i = 0; i < WIDTH; i++) {
(ATOM -> grid)[i] = malloc(HEIGHT * sizeof(grid_t));
for (int j = 0; j < HEIGHT; j++) {
(ATOM -> grid)[i][j] = *nullGrid;
}
}
//free(nullGrid); <- do I do this now?
return;
}
Firstly, don't cast the return from malloc(). It is not required in C, and can obscure serious errors.
Second, don't hard-code the type into the malloc() call. For example,
ATOM->grid = (grid_t**) malloc(WIDTH * sizeof(grid_t*));
would be replaced by
ATOM->grid = malloc(WIDTH * sizeof(*(ATOM->grid)));
This ensures the memory allocated is of the required size, regardless of what ATOM->grid is a pointer to.
To answer your question, to release all memory, you need to pass every nonNULL pointer returned by malloc() to free(). Exactly once.
So, if you allocate like this
ATOM->grid = malloc(WIDTH * sizeof(*(ATOM->grid)));
grid_t *nullGrid = malloc(sizeof(*nullGrid));
grid_t temp = {NULL, 0};
*nullGrid = temp;
for (int i = 0; i < WIDTH; i++)
{
(ATOM -> grid)[i] = malloc(HEIGHT * sizeof(*((ATOM->grid)[i])));
for (int j = 0; j < HEIGHT; j++) {
(ATOM -> grid)[i][j] = *nullGrid;
}
the one way of deallocating would be
for (int i = 0; i < WIDTH; i++)
{
free((ATOM -> grid)[i]);
}
free(ATOM->grid);
free(nullGrid);
In this case, you cannot safely free(ATOM->grid) before any free((ATOM -> grid)[i]) (unless you store all of the (ATOM->grid)[i] somewhere else, which sort of defeats the point). The individual (ATOM->grid)[i] may be freed in any order (as long as each is released exactly once).
Lastly, check the pointers returned by malloc(). It returns NULL when it fails, and dereferencing a NULL pointer gives undefined behaviour.
Yes, you need to free(nullGrid); here to avoid a memory leak.
But actually you can simplify your code to this:
void createGridArray(atom_t* ATOM) {
ATOM -> grid = (grid_t**) malloc(WIDTH * sizeof(grid_t*));
grid_t nullGrid = {NULL, 0};
for (int i = 0; i < WIDTH; i++) {
(ATOM -> grid)[i] = malloc(HEIGHT * sizeof(grid_t));
for (int j = 0; j < HEIGHT; j++) {
(ATOM -> grid)[i][j] = nullGrid;
}
}
}
There is need for mallocing nullGrid here at all. BTW the return at the end of a void function is implicit.
You wouldn't do this either:
void Foo()
{
...
int *temp = malloc(sizeof(int));
*temp = ...;
...
bar = *temp;
...
free(temp);
}
but rather:
void Foo()
{
...
int temp
temp = ...;
...
bar = temp;
...
}
The C memory allocation is easier when you think it as a "loan".
Somehow, the system loan you some memory when you call malloc(), and you have to give it back with free().

How to work on a sub-matrix in a matrix by pointer?

I have a matrix of size n. Take an example:
My recursive function does the processing on the elements that lie in the border of the matrix. Now I want to call it (the recursive call) on the inner square matrix:
This is the prototype of my recursive function:
void rotate(int** mat, size_t n);
I know that a 2D array is an array within an array. I know that *(mat+1) + 1) will give the memory address that should be the base address of my new matrix. This is what I tried:
rotate((int **)(*(mat+1) + 1), n-2)
But it does not work, and I get a segfault when I try to access it with [][].
You cannot dereference mat+1 and reinterpret that as a pointer to a whole matrix. Instead provide the offsets as arguments to your function (I assume n-by-n square matrices):
void rotate(int** mat, size_t i, size_t j, size_t n) {
// assuming row-wise storage
int *row0 = mat[j]; // assumes j < n
int *row1 = mat[j + 1]; // assumes j + 1 < n
// access row0[i..] and row1[i..]
}
If you had continuous storage for your matrix, you could do the following instead:
rotate(int* mat, size_t i, size_t j, size_t n) {
int atIJ = mat[j * n + i]; // assuming row-wise storage
// ...
}
I am not sure of your application, but I wonder if using #define for your matrix size would help....
#define X_SIZE 4
#define Y_SIZE 4
or even
#define N_SIZE 4
... because then you can use X_SIZE and Y_SIZE (OR N_SIZE) in your function without having to pass them explicitly.
in main you might put
int matrix[X_SIZE * Y_SIZE];
or
int matrix2[N_SIZE * N_SIZE];
then you can call the ith row and jth column element with
*(pmatrix + X_SIZE*j + i)
or
matrix[X_SIZE*j + i]
or
*(pmatrix2 + N_SIZE*j + i)
or
matrix2[N_SIZE*j + i]
where pmatrix and pmatrix2 are pointers to matrix and matrix2.
I am pretty sure there is no clever trick to be able to easily pass the inner square 2x2 matrix to a function, unless you were to copy the elements from the centre of your matrix into a new matrix and then copy back the result afterwards.
This is not an answer to the stated question, but it is an answer to the underlying problem: management of matrices and views to matrices with minimal effort.
This will garner downvotes, but it has been so useful in solving the underlying problems whenever the type of question the OP poses has been asked, I find it is worth showing this alternative approach here.
It is not interesting for small, fixed-size matrices, as the features only show their benefits when the sizes are larger or vary.
I use the following two structures to describe matrices. I shall leave out memory pool support (which allows one to manage a set of matrices as a pool, releasing them all at once, without having to manage each matrix separately) and everything related to multithreaded operation and thread-safety, for simplicity.
The code might contain typos; if you notice any, please leave a comment, and I'll fix them.
typedef int data_t; /* Matrix element data type */
struct owner {
long refcount; /* Number of referenced to this data */
size_t size; /* Number of elements in data[] */
data_t data[]; /* C99 flexible array member */
};
typedef struct {
int rows; /* Number of rows in this matrix */
int cols; /* Number of columns in this matrix */
long rowstride;
long colstride;
data_t *origin; /* Pointer to element at row 0, col 0 */
struct owner *owner; /* Owner structure origin points to */
} matrix;
#define MATRIX_INIT { 0, 0, 0L, 0L, NULL, NULL }
Matrix m element at row r, column c, is m.origin[r * m.rowstride + c * m.colstride], assuming 0 <= r && r < m.rows and 0 <= c < m.cols.
Matrices are typically declared as local variables, not as pointers. You do need to remember to free each individual matrix after you no longer need it. (The pool mechanism I omitted lets you avoid this, as all matrices in a pool are freed at once.)
Each matrix refers to exactly one owner structure. Owner structures record the number of references (the number of matrices referring to data in that structure), and are released when the reference count drops to zero:
void matrix_free(matrix *const m)
{
if (m != NULL) {
if (m->owner != NULL && --(m->owner.refcount) < 1L) {
m->owner.size = 0;
free(m->owner);
}
m->rows = 0;
m->cols = 0;
m->rowstride = 0L;
m->colstride = 0L;
m->origin = NULL;
m->owner = NULL;
}
}
Whenever a new matrix is created, the corresponding owner structure is created:
int matrix_new(matrix *const m, const int rows, const int cols)
{
const size_t size = (size_t)rows * (size_t)cols;
struct owner *o;
if (m == NULL)
return errno = EINVAL;
m->rows = 0;
m->cols = 0;
m->rowstride = 0L;
m->colstride = 0L;
m->origin = NULL;
m->owner = NULL;
if (rows < 1 || cols < 1)
return errno = EINVAL;
o = malloc(sizeof (struct owner) + size * sizeof (data_t));
if (o == NULL) {
return errno = ENOMEM;
o->refcount = 1L;
o->size = size;
m->rows = rows;
m->cols = cols;
m->origin = o->data;
m->owner = o;
#if DEFAULT_COLUMN_MAJOR > 0
/* Default to column-major element order */
m->rowstride = 1L;
m->colstride = (long)rows;
#else
/* Default to row-major element order */
m->rowstride = (long)cols;
m->colstride = 1L;
#endif
return m;
}
Note that the above does not initialize the matrix elements to any value, so they initially contain garbage.
Matrix transpose is a trivial, fast operation:
void matrix_transpose(matrix *const m)
{
if (m->rows > 0 && m->cols > 0) {
const int rows = m->rows;
const int cols = m->cols;
const long rowstride = m->rowstride;
const long colstride = m->colstride;
m->rows = cols;
m->cols = rows;
m->rowstride = colstride;
m->colstride = rowstride;
}
}
Similarly, you can rotate and mirror matrices, just remember to modify the origin member in those cases, too.
The interesting and useful cases are being able to create "views" into other matrices. The data referenced is exactly the same -- modifying one is immediately visible in the other(s); this is true aliasing --, no memory copying is needed. Unlike in most libraries (such as GSL, GNU Scientific Library), these "views" are perfectly ordinary matrices themselves. Here are some examples:
int matrix_submatrix_from(matrix *const m, const matrix *const src,
const int firstrow, const int firstcol,
const int rows, const int cols)
{
if (m == NULL || m == src)
return errno = EINVAL;
m->rows = 0;
m->cols = 0;
m->rowstride = 0L;
m->colstride = 0L;
m->origin = NULL;
m->owner = NULL;
if (firstrow + rows > src->rows ||
firstcol + cols > src->cols)
return errno = EINVAL;
if (src == NULL || src->owner == NULL)
return errno = EINVAL;
if (src->owner.refcount < 1L || src->owner.size == 0)
return errno = EINVAL;
else {
++(src->owner.refcount);
m->owner = src->owner;
}
m->origin = src->origin + src->rowstride * firstrow
+ src->colstride * firstcol;
m->rows = rows;
m->cols = cols;
m->rowstride = src->rowstride;
m->colstride = src->colstride;
return 0;
}
int matrix_transposed_from(matrix *const m, const matrix *const src)
{
if (m == NULL || m == src)
return errno = EINVAL;
m->rows = 0;
m->cols = 0;
m->rowstride = 0L;
m->colstride = 0L;
m->origin = NULL;
m->owner = NULL;
if (src == NULL || src->owner == NULL)
return errno = EINVAL;
if (src->owner.refcount < 1L || src->owner.size == 0)
return errno = EINVAL;
else {
++(src->owner.refcount);
m->owner = src->owner;
}
m->origin = src->origin;
m->rows = src->cols;
m->cols = src->rows;
m->rowstride = src->colstride;
m->colstride = src->rowstride;
return 0;
}
Using code similar to above, you can create one-row or one-column matrix views describing any row, column, or diagonal. (The diagonals are especially useful in certain situations.)
Submatrices can be mirrored or rotated, and so on.
You can safely free a matrix you only need a submatrix or other view from, as the owner structure reference count keeps track of when the data can be safely discarded.
Matrix multiplication, and other similar complex operations for larger matrices, are very sensitive to cache locality issues. This means that you are better off copying the source matrix data into compact arrays (with the arrays properly aligned and in elements in correct order for that operand). The overhead caused by both row and column having a separate stride (instead of only one, as is typical) is actually minimal; in my own tests, neglible.
The best feature of this approach, however, is that it lets you write efficient code without worrying about what is a "real" matrix, what is a "view", and how the actual underlying data is stored in an array, unless you care.
Finally, it is simple enough for anyone who grasps basic dynamic memory management in C to completely understand.

function to modify 2d array to add row an a column using realloc

Whats wrong with this function, which is expected to add a row and a column to given 2D array? Matrix is symmetric.
void updateMatrix(double ***mat, int size, double *vec)
{ // mat is sizeXsize matrix, length of vec is size+1
*mat = (double**)realloc(*mat, (size + 1)*sizeof(double*));
(*mat)[size] = (double*)malloc((size + 1)*sizeof(double));
for(int i = 0; i < size + 1; i++) {
(*mat)[size][i] = vec[i];
}
for(int i = 0; i < size; i++) {
(*mat)[i] = (double*)realloc((*mat)[i], (size + 1)*sizeof(double));
(*mat)[i][size] = vec[i];
}
}
Your realloc is returning NULL in the second for loop..
I'm trying to figure out why.
Have you allocated everything before hand? Because chances are you might be passing a non NULL and non malloced pointer to realloc. And that is forbidden/will cause errors
Or, as says #MichaelDorgan , you could just be passing a gigantic size to your function but i sincereley hope you are not trying to allocate a few Go for an array. Otherwise i'm curious as to its use.

C-Passing an 3d array,allocation and population

let's say I have a functions below.
void function createBands(boolean option) {
int i, j;
int ***bands = (int ***)malloc((SIZE + 1) * sizeof(int **));
for (i = 0; i < SIZE; i++) {
bands[i] = (int **)malloc(HEIGHT * sizeof(int *));
for (j = 0; j < HEIGHT; j++)
bands[i][j] = (int *)malloc(WIDTH * sizeof(int));
}
iterator *it =
createIterator(params); // do not be confused it is a structure with
// methods andaeribute just like Iterator class in
// java . Methods are poniters to functions.
repare_array(bands[Size], it);
}
void prepare_array(int **band, iterator *it) { read_array(band, it); }
read_array(int **band, iterator *it) {
for (int i = 0; i < Height; i++)
band[i] = (int *)it->next();
}
// Now in Iterator.c I have the iterator structure with the methods etc I will
// write just some line form iterator.
void *next() {
byte *b =
a function that reads bytes form a file and returns byte * CORECTLY !!!;
return b == NULL ? NULL : bytetoT(b);
// this function make void form byte conversion but it doesnt work so I make
// only a cast in read_aray as you see. SUppose just return b wich is byte(i
// know in C isn't any byte but I redeclared all the types to be JAVA.)
}
the questions is where I should allocate the bands because in this situation the 1D vector return by function is ok because I see the values in the function scope. But when it is return to array[i] I got a unallocated 3dVector.
I need to recieve bands[size][i][j] with the data form b. In b the data is good then I ve gote bands null.
What I have do so far I make another allocation in prepare aray before the call to read_array where I allocate **band and then I have some results but I am not confident.
Sorry for the confusion! And every comment is good for me. Maybe what I have do is ok I do not know!.
I am not new to C I just do not work with pointers for a long time.
If it is a 2D pointer(**) you have to assign it with the address of 2D array and if it is 1D array you have to assign it with the address of 1D array.
For your read_array function
read_array(int**array...)
{
for(i=0;i<HEIGHT(the same as in allocation);i++)
`enter code here`array[i] = function();//function return an 1D array
}
Make sure that function() returns the address of the 1D array.

Resources