How to shrink at runtime a struct matrix
(using reallocate() for example)
I have a struct
matrix which I use to set a vector of size 3 with entries (1
,2
,3
). How is it possible to shrink the size of the vector to retain the 2 first elements and remove the third one (the 3
)? I tried to use realloc()
without success
At the end I would like to have the following output:
1 2 3
1 2
Here is the code:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
size_t nrows, ncols;
size_t *array;
} Matrix ;
int ncol = 3;
int nrow = 1;
void print_matrix(Matrix * matrix);
int main()
{
Matrix *mat1 = (Matrix *) malloc(sizeof(Matrix));
mat1->nrows = nrow;
mat1->ncols = ncol;
mat1->array = (size_t *) malloc(mat1->nrows * mat1->ncols * sizeof(int));
mat1->array[0 * ncol + 0] = 1;
mat1->array[0 * ncol + 1] = 2;
mat1->array[0 * ncol + 2] = 3;
print_matrix(mat1);
mat1->nrows = mat1->nrows - 1;
mat1->array = (size_t *) realloc(mat1, nrow * ncol * sizeof(int));
print_matrix(mat1);
free(mat1);
}
void print_matrix(Matrix * matrix)
{
for (size_t row =0; row<matrix->nrows; row++)
{
for (size_t col =0; col<matrix->ncols; col++)
{
printf("%zu ", matrix->array[row * ncol + col]);
}
printf("\n");
}
}
EDIT Thanks to the answer here is the working code:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
size_t nrows, ncols;
size_t *array;
} Matrix ;
int ncol = 3;
int nrow = 1;
void print_matrix(Matrix * matrix);
int main()
{
Matrix *mat1 = (Matrix *) malloc(sizeof(Matrix));
mat1->nrows = nrow;
mat1->ncols = ncol;
mat1->array = (size_t *) malloc(mat1->nrows * mat1->ncols * sizeof(*mat1->array));
if (mat1 == NULL)
{
printf("Could not allocate memory\n");
exit(EXIT_FAILURE);
}
else
{
mat1->nrows = nrow;
mat1->ncols = ncol;
mat1->array = (size_t *) malloc(mat1->nrows * mat1->ncols * sizeof(*mat1->array));
mat1->array[0 * ncol + 0] = 1;
mat1->array[0 * ncol + 1] = 2;
mat1->array[0 * ncol + 2] = 3;
print_matrix(mat1);
mat1->ncols = mat1->ncols - 1;
mat1->array = (size_t *) realloc(mat1->array, mat1->nrows * mat1->ncols * sizeof(*mat1->array));
if (mat1 == NULL)
{
printf("Could not allocate memory\n");
exit(EXIT_FAILURE);
}
print_matrix(mat1);
free(mat1);
}
}
void print_matrix(Matrix * matrix)
{
for (size_t row =0; row<matrix->nrows; row++)
{
for (size_t col =0; col<matrix->ncols; col++)
{
printf("%zu ", matrix->array[row * ncol + col]);
}
printf("\n");
}
}
mat1
but mat1->array
should be reallocated.nrow
and ncol
(not updated) but mat1->nrows
and mat1->ncols
(updated) should be used for the new size.size_t
, so allocating for int
mayn't be enough. Using the variable for calculating size is safe.In the other words, this part
mat1->nrows = mat1->nrows - 1;
mat1->array = (size_t *) realloc(mat1, nrow * ncol * sizeof(int));
should be
mat1->ncols = mat1->ncols - 1;
mat1->array = (size_t *) realloc(mat1->array, mat1->nrows * mat1->ncols * sizeof(*mat1->array));
and the part (the 4th line of main()
body)
mat1->array = (size_t *) malloc(mat1->nrows * mat1->ncols * sizeof(int));
should be
mat1->array = (size_t *) malloc(mat1->nrows * mat1->ncols * sizeof(*mat1->array));
Note that this simple reallocation works only because the matrix has only one row. For matrice having multiple rows, you should move (using memmove
or manually) second and later rows to match the new number of columns.