如何在运行时缩小一个结构矩阵(例如使用realloc())

huangapple go评论66阅读模式
英文:

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

问题

如何在运行时缩小结构体 matrix 的大小(例如使用 reallocate()

我有一个名为 matrix 的结构体,我用它来设置一个包含条目 (1, 2, 3) 的大小为 3 的向量。如何将向量的大小缩小,以保留前两个元素并删除第三个元素(3)?我尝试使用 realloc(),但没有成功。

最终,我想要以下输出:

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("无法分配内存\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("无法分配内存\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");
  }
}
英文:

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 &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
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-&gt;nrows = nrow;
mat1-&gt;ncols = ncol;
mat1-&gt;array = (size_t *) malloc(mat1-&gt;nrows * mat1-&gt;ncols * sizeof(int));
mat1-&gt;array[0 * ncol + 0] = 1;
mat1-&gt;array[0 * ncol + 1] = 2;
mat1-&gt;array[0 * ncol + 2] = 3;
print_matrix(mat1);
mat1-&gt;nrows = mat1-&gt;nrows - 1;
mat1-&gt;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&lt;matrix-&gt;nrows; row++)
{
for (size_t col =0; col&lt;matrix-&gt;ncols; col++)
{
printf(&quot;%zu &quot;, matrix-&gt;array[row * ncol + col]);
}
printf(&quot;\n&quot;);
}
}

EDIT
Thanks to the answer here is the working code:

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
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-&gt;nrows = nrow;
mat1-&gt;ncols = ncol;
mat1-&gt;array = (size_t *) malloc(mat1-&gt;nrows * mat1-&gt;ncols * sizeof(*mat1-&gt;array));
if (mat1 == NULL)
{
printf(&quot;Could not allocate memory\n&quot;);
exit(EXIT_FAILURE);
}
else
{
mat1-&gt;nrows = nrow;
mat1-&gt;ncols = ncol;
mat1-&gt;array = (size_t *) malloc(mat1-&gt;nrows * mat1-&gt;ncols * sizeof(*mat1-&gt;array));
mat1-&gt;array[0 * ncol + 0] = 1;
mat1-&gt;array[0 * ncol + 1] = 2;
mat1-&gt;array[0 * ncol + 2] = 3;
print_matrix(mat1);
mat1-&gt;ncols = mat1-&gt;ncols - 1;
mat1-&gt;array = (size_t *) realloc(mat1-&gt;array, mat1-&gt;nrows * mat1-&gt;ncols * sizeof(*mat1-&gt;array));
if (mat1 == NULL)
{
printf(&quot;Could not allocate memory\n&quot;);
exit(EXIT_FAILURE);
}
print_matrix(mat1);
free(mat1);
}
}
void print_matrix(Matrix * matrix)
{
for (size_t row =0; row&lt;matrix-&gt;nrows; row++)
{
for (size_t col =0; col&lt;matrix-&gt;ncols; col++)
{
printf(&quot;%zu &quot;, matrix-&gt;array[row * ncol + col]);
}
printf(&quot;\n&quot;);
}
}

答案1

得分: 3

  • 你应该减少列数,而不是行数。
  • 不是mat1,而是mat1->array应该重新分配。
  • 不是nrowncol(未更新),而是mat1->nrowsmat1->ncols(已更新)应该用于新的大小。
  • 这些元素是size_t类型,所以为int类型分配内存可能不够。使用变量来计算大小是安全的。

换句话说,这部分

  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));

以及主函数main()体中的第4行部分

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

应该改为

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

请注意,这种简单的重新分配仅适用于具有单行的矩阵。对于具有多行的矩阵,您应该移动(使用memmove或手动移动)第二行及更高行以匹配新的列数。

英文:
  • You should reduce the number of columsn, not rows.
  • Not mat1 but mat1-&gt;array should be reallocated.
  • Not nrow and ncol (not updated) but mat1-&gt;nrows and mat1-&gt;ncols (updated) should be used for the new size.
  • The elements are 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-&gt;nrows = mat1-&gt;nrows - 1;
  mat1-&gt;array = (size_t *) realloc(mat1, nrow * ncol * sizeof(int));

should be

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

and the part (the 4th line of main() body)

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

should be

  mat1-&gt;array = (size_t *) malloc(mat1-&gt;nrows * mat1-&gt;ncols * sizeof(*mat1-&gt;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.

huangapple
  • 本文由 发表于 2023年3月3日 19:09:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75626327.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定