C语言 将 2D 数组转换为动态数组会导致核心转储



我有一个完美的工作代码,其中包含 C 语言的浮点变量 vxy 的 2D 数组。行 (rrow( 的大小是在代码内部计算的 - 列 (ccol( 大小是已知的。所以我尝试在这个论坛中使用代码片段进行转换,两者都会导致分段错误。这两个代码是 i( 来自如何为二维数组动态分配内存的 Brian 方法和 ii( 使用指针指向 http://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/的指针方法。我之所以选择这些方法,是因为代码已经可以与 2D 数组一起使用,因此其余代码将在此更改中幸存下来。

static float vxy[5000][ccol] ;
vxy[r][c] = ... 

原始 2D 声明和用法如上:

#include <stdlib.h>
int main(void)
{
        int num_row = 3, num_col = 2, r;
        int ** A;
        A = malloc(num_row*(sizeof(*A)+num_col*sizeof(**A)));
        for (r = 0; r < num_row; r++)
        {
                A[r] = (int*)(A+num_row)+r*num_col;
        }
        /* Accessing element at row r and column c is through:
         *
         *      A[r][c].
         */
        free(A);
        return 0;
}

我基于上述的实现是:

int r;
float ** vxy;
    vxy = malloc(rrow*(sizeof(*vxy)+ ccol*sizeof(**vxy)));
    for (r = 0; r < rrow; r++)  {
        vxy[r] = (float*)(vxy + rrow) + r*ccol;
    }

第二种方法是:

        float **vxy = (float **)malloc(rrow * sizeof(float *));
        for (i=0; i<rrow; i++)
             vxy[i] = (float *)malloc(ccol * sizeof(float));

我用以下内容更新了上述第二种方法 - 我在 vxy[i] = malloc(ccol * sizeof(float((的行上得到了"程序接收信号 SIGSEGV,分段错误";

    float **vxy = malloc(rrow * sizeof(float *));
    if (vxy = NULL) {
          printf ("Memory allocation error.n");
//        return NULL;
    }
    for (i = 0; i < rrow; i++)
        vxy[i] = malloc(ccol * sizeof(float)); 

我的实现似乎出了什么问题?更新:我从方法一的源代码更新了完整代码。我还想知道如何释放分配并解决失败的malloc情况。

很抱歉您在 2D 分配时遇到困难,这真的不太难。要使用array[x][y]表示法动态分配和访问元素,您需要将x指针分配给float数组(您的行(,然后为每行分配一个float数组(您的元素/列(y数组。(与将指针数组分配给字符串以保存文本行没有什么不同(

显示

calloc(m行和n列(而不对分配进行错误检查简单分配/初始化函数的示例是:

float **mtrx_calloc (size_t m, size_t n)
{
    register size_t i;
    float **array = calloc (m, sizeof *array);
    for (i = 0; i < m; i++)
    {
        array [i] = calloc (n, sizeof **array);
    }
    return array;
}

要分配3x4矩阵,您可以像这样使用它:

float **matrix = mtrx_calloc (3, 4);

然后,您可以根据需要使用matrix[x][y]表示法访问所有元素来操作矩阵。另请注意使用 size_t 而不是 int 。您的rowscolumnsiterator永远不会是负数,因此选择size_tunsigned类型更有意义。

有时,与其查看代码片段,不如有一个工作示例。我整理了一个简短的工作示例来帮助您,其中包括我们迄今为止在评论和上面讨论的所有要点。它包括上面省略的内存分配错误检查。如果您有任何疑问,请发表评论。

#include <stdio.h>
#include <stdlib.h>
float **mtrx_calloc (size_t m, size_t n);             /* initialize elements to 0  */
void mtrx_prn (size_t m, size_t n, float **matrix);   /* print matrix with/pad     */
void mtrx_free (size_t m, float **matrix);            /* free memory allocated     */
int main (void)
{
    /* allocate the 3x4 matrix */
    float **matrix = mtrx_calloc (3, 4);
    /* fill with misc values */
    register size_t i = 0, j = 0;
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 4; j++)
            matrix [i][j] = (float)(i + j);
    }
    /* print matrix */
    printf ("nThe dynamically allocated 3x4 matrix is:nn");
    mtrx_prn (3, 4, matrix);
    /* free memory alocated */
    mtrx_free (3, matrix);
    /* just to make it look pretty */
    printf ("n");
    return 0;
}
/* allocate/initialize mxn matrix */
float **mtrx_calloc (size_t m, size_t n)
{
    register size_t i;
    float **array = calloc (m, sizeof *array);
    if (!array) {   /* validate allocation  */
        fprintf (stderr, "%s() error: memory allocation failed.n", __func__);
        exit (EXIT_FAILURE);
    }
    for (i = 0; i < m; i++)
    {
        array[i] = calloc (n, sizeof **array);
        if (!array[i]) {   /* validate allocation  */
            fprintf (stderr, "%s() error: memory allocation failed.n", __func__);
            exit (EXIT_FAILURE);
        }
    }
    return array;
}
/* print a (m x n) matrix (check pad alloc) */
void mtrx_prn (size_t m, size_t n, float **matrix)
{
    register size_t i, j;
    for (i = 0; i < m; i++)
    {
        char *pad = "[ ";
        for (j = 0; j < n; j++)
        {
            printf ("%s%6.3f", pad, matrix [i][j]);
            pad = ", ";
        }
        printf ("%s", " ]n");
    }
}
void mtrx_free (size_t m, float **matrix)
{
    register size_t i;
    for (i = 0; i < m; i++)
    {
        free (matrix [i]);
    }
    free (matrix);
}

输出

(注意:填充杂项值公式已更改,以防止在进入大m x n时溢出,因此输出值将与下面不同(

$ ./bin/mtrx_dyn_example
The dynamically allocated 3x4 matrix is:
[  1.900,  2.800,  3.700,  4.600 ]
[  2.800,  3.700,  4.600,  5.500 ]
[  3.700,  4.600,  5.500,  6.400 ]

使用瓦尔格林德进行泄漏检查

动态创建/分配内存块时,

负责跟踪已分配的内容,保留内存块的起始地址,并在不再需要内存块时释放内存块。帮助您检查内存使用情况的好工具是内存检查器,例如 valgrind .(类似的工具适用于所有平台(。简单易用,只需valgrind ./progname.它将为您确认是否有任何块仍未释放,以及是否存在有关您分配的块的任何访问错误:

$ valgrind ./bin/mtrx_dyn_example
==15800== Memcheck, a memory error detector
==15800== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==15800== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==15800== Command: ./bin/mtrx_dyn_example
==15800==
The dynamically allocated 3x4 matrix is:
[  1.900,  2.800,  3.700,  4.600 ]
[  2.800,  3.700,  4.600,  5.500 ]
[  3.700,  4.600,  5.500,  6.400 ]
==15800==
==15800== HEAP SUMMARY:
==15800==     in use at exit: 0 bytes in 0 blocks
==15800==   total heap usage: 4 allocs, 4 frees, 72 bytes allocated
==15800==
==15800== All heap blocks were freed -- no leaks are possible
==15800==
==15800== For counts of detected and suppressed errors, rerun with: -v
==15800== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

问题在于指向浮点数的指针和实际浮点数之间的相互作用,如参考答案中所述,尝试删除类型转换并查看您得到的结果。

这两种方法都是有效的(但以不同的方式访问(,还有

第一种方法创建一个表示 2d 数组的一维数组(因此作为 a[i+j*r] 访问(,而(第一和(第二种方法实际上分配一个二维数组(作为a[i][j]访问(。

如果有帮助,也可以尝试使用 calloc,尽管 malloc 应该没问题

使用任一方法时,还要尝试正确修复索引(在循环中(,以确保不会越界访问分配数组中的内存

相关内容

  • 没有找到相关文章