C-在动态矩阵上设置指针



我正在尝试制作1字节元素的动态大小矩阵。为此,我定义了以下功能。当我尝试设置矩阵的第一个" nrows"元素以指向相应的行时,问题出在问题(因此我可以做矩阵[i] [j])。看来matrix[i] = matrix[nrows + i * single_row_elements_bytes];的工作原理不够好(该程序编译,但会引发核心细分侵犯错误)。我该如何做这项工作?

uint8_t **NewMatrix(unsigned nrows, unsigned ncols)
{
    uint8_t **matrix;
    size_t row_pointer_bytes = nrows * sizeof *matrix;
    size_t single_row_elements_bytes = ncols * sizeof **matrix;
    matrix = malloc(row_pointer_bytes + nrows * single_row_elements_bytes);
    unsigned i;
    for(i = 0; i < nrows; i++)
        matrix[i] = matrix[nrows + i * single_row_elements_bytes];
    return matrix;
}

除了另一个答案中提到的各种错误外,您正在错误地分配2D数组。实际上,您根本不是分配一个2D数组,而是一个缓慢而零散的查询表。

在如何正确设置,访问和释放c?中的多维数组的方式上,动态分配2D数组的正确方法。详细说明了该功能如何工作以及阵列指针的工作方式,以动态分配矩阵。

这是使用上述技术的示例,用于您的特定情况:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <inttypes.h>
void NewMatrix (size_t nrows, size_t ncols, uint8_t (**matrix)[nrows][ncols])
{
  *matrix = malloc ( sizeof (uint8_t[nrows][ncols]) );
}

int main (void) 
{
  size_t r = 3;
  size_t c = 4;
  uint8_t (*arr_ptr)[r][c];
  NewMatrix(r, c, &arr_ptr);
  uint8_t (*matrix)[c] = arr_ptr[0];
  uint8_t count=0;
  for(size_t i=0; i<r; i++)
  {
    for(size_t j=0; j<c; j++)
    {
      matrix[i][j] = count;
      count++;
      printf("%2."PRIu8" ", matrix[i][j]);
    }
    printf("n");
  }
  free(arr_ptr);
}

我认为您的代码有两个问题。

  • 您可以简化此行:

    matrix = malloc(row_pointer_bytes + nrows * single_row_elements_bytes);
    

    to:

    matrix = malloc(row_pointer_bytes);
    

    在矩阵中为uint8_t*分配空间。

    malloc()函数仅需要size_t在堆上分配请求的内存所需的字节数量,并返回指针。

    可以简单地通过知道矩阵中需要多少行来分配,在这种情况下为nrows

  • 此外,您的循环:

    for(i = 0; i < nrows; i++)
        matrix[i] = matrix[nrows + i * single_row_elements_bytes];
    

    不是为matrix[i]分配内存,因为每行都有n列,因此您需要为这些列分配内存。

    这应该是:

    for(i = 0; i < nrows; i++)
        matrix[i] = malloc(single_row_elements_bytes);
    
  • 另一个问题是如何分配single_row_elements_bytes。而不是:

    size_t single_row_elements_bytes = ncols * sizeof **matrix; //**matrix is uint8_t**
    

    这需要为n列分配uint8_t字节,而不是uint8_t**字节。可以是这样:

    size_t single_row_elements_bytes = ncols * sizeof(uint8_t);
    

这样说,如果这样写的话,您的代码将编译。这是我写的示例以测试代码。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
uint8_t **NewMatrix(unsigned nrows, unsigned ncols);
int
main(int argc, char *argv[]) {
    uint8_t **returnmatrix;
    unsigned nrows = 2, ncols = 2;
    int i, j;
    returnmatrix = NewMatrix(nrows, ncols);
    for (i = 0; i < nrows; i++) {
        for (j = 0; j < ncols; j++) {
            printf("Enter number for row %d column %d: ", i+1, j+1);
            /* format speficier for uint8_t, from <inttypes.h> */
            if (scanf("%"SCNu8"", &returnmatrix[i][j]) != 1) {
                printf("Invalid 8 bit number.n");
                exit(EXIT_FAILURE);
            }
        }
    }
    printf("nYour matrix:n");
    for (i = 0; i < nrows; i++) {
        for (j = 0; j < ncols; j++) {
            printf("%d ", returnmatrix[i][j]);
        }
        printf("n");
    }
    /* Good to free at the end */
    free(returnmatrix);
    return 0;
}
uint8_t 
**NewMatrix(unsigned nrows, unsigned ncols) {
    int i;
    uint8_t **matrix;
    size_t row_pointer_bytes = nrows * sizeof * matrix;
    size_t column_row_elements_bytes = ncols * sizeof(uint8_t);
    matrix = malloc(row_pointer_bytes);
    /* Good to check return value */
    if (!matrix) {
        printf("Cannot allocate memory for %d rows.n", nrows);
        exit(EXIT_FAILURE);
    }
    for(i = 0; i < nrows; i++) {
        matrix[i] = malloc(column_row_elements_bytes);
        if (!matrix[i]) {
            printf("Cannot allocate memory for %d columns.n", ncols);
            exit(EXIT_FAILURE);
        } 
    } 
    return matrix;
}

输入:

Enter number for row 1 column 1: 1
Enter number for row 1 column 2: 2
Enter number for row 2 column 1: 3
Enter number for row 2 column 2: 4

输出:

Your matrix:
1 2
3 4

编译:

gcc -Wall -o matrix matrix.c
    for (i=0;i<nrows;i++)
            matrix[i] = (uint8_t *)malloc(ncols * sizeof(uint8_t));

以下2行必须用以上2行替换

    for(i = 0; i < nrows; i++)
          matrix[i] = matrix[nrows + i * single_row_elements_bytes];

(nrows + i * single_row_elements_bytes)为分配大小,并且nrows = 5ncols =5(例如,总共分配了65个字节。其中包括40个字节来存储行指针(假设有64位指针尺寸)和REST 25个字节存储每个R,C元素的内容。但是,未分配列指针的内存(指向该行中的每个元素的指针)。

所以,删除matrix[i][j]将出现故障。

最新更新