如何在运行时收缩结构矩阵(例如,使用 realloc())

How to shrink at runtime a struct matrix (using realloc() for example)

提问人:ecjb 提问时间:3/3/2023 最后编辑:ecjb 更新时间:3/3/2023 访问量:43

问:

如何在运行时收缩结构(例如,使用 reallocate())matrix

我有一个矩阵,我用它来设置一个大小为 3 的向量,其中包含条目 (,,)。如何缩小向量的大小以保留前 2 个元素并删除第三个元素 ()?我尝试使用但没有成功struct1233realloc()

最后,我希望得到以下输出:

1 2 3
1 2

代码如下:

#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");
  }
}

编辑多亏了答案,这里是工作代码:

#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");
  }
}

阵列 C 矩阵 malloc realloc

评论

1赞 Harith 3/3/2023
旁白:不要强制转换 and family 的返回值,但要检查其返回值。它返回以指示失败。malloc()NULL
0赞 Harith 3/3/2023
sizeof(int)应该是 .并且等价于 。sizeof(size_t)[0 * ncol + 0][0]
0赞 Weather Vane 3/3/2023
我认为您需要使用具有多行的示例,并使用双指针。对于一维数组,当您更改其大小时,您必须重新组织其内容。
0赞 Harith 3/3/2023
如果失败,您将无法访问通过 分配的原始内存。使用临时指针来保存 的值。mat1->array = (size_t *) realloc(mat1, nrow * ncol * sizeof(int));malloc()realloc()

答:

3赞 MikeCAT 3/3/2023 #1
  • 您应该减少列数,而不是行数。
  • 不是,但应该重新分配。mat1mat1->array
  • Not 和 (not updated) but and (updated) 应用于新大小。nrowncolmat1->nrowsmat1->ncols
  • 元素是 ,所以分配可能还不够。使用变量计算大小是安全的。size_tint

换句话说,这部分

  mat1->nrows = mat1->nrows - 1;
  mat1->array = (size_t *) realloc(mat1, nrow * ncol * sizeof(int));

应该是

  mat1->ncols = mat1->ncols - 1;
  mat1->array = (size_t *) realloc(mat1->array, mat1->nrows * mat1->ncols * sizeof(*mat1->array));

和部分(身体的第 4 行)main()

  mat1->array = (size_t *) malloc(mat1->nrows * mat1->ncols * sizeof(int));

应该是

  mat1->array = (size_t *) malloc(mat1->nrows * mat1->ncols * sizeof(*mat1->array));

请注意,这种简单的重新分配之所以有效,是因为矩阵只有一行。对于具有多行的矩阵,应移动(使用或手动)第二行和更高行以匹配新的列数。memmove

评论

0赞 Arkku 3/3/2023
此外,在 中,global 用于一个地方。print_matrixncol
1赞 Andrew Henle 3/3/2023
您应该移动(使用 MemMove 或手动)第二行和更高行以匹配新的列数。如果要缩小数组,则必须在调用之前完成,如果要增加数组,则必须在调用之后完成。realloc()realloc()