繁体   English   中英

动态分配的数组中的意外数据/意外段错误(供二维使用)

[英]Unexpected data/unexpected segfault in a dynamically allocated array (for two dimensional use)

我试图以最有效和最简洁的方式在C中创建2D矩阵(基本上是任何给定大小的动态可分配2d数组)。 我已经在一个较大的项目中实现了这样的事情,但是遇到了问题,因此可以将其范围缩小到以下范围。

我决定先分配一个巨型数组(我称其为数据),然后创建一个指针数组(即其称为单元格),以便能够以这样的方式在大数组中寻址数据:维上下文(如在matrix [x] [y]中,而不是data [每次都使用丑陋的指针算术]。)我认为这将是一个好主意,因为它只调用一次malloc,因此分配的速度也更快内存位于一个连续的块中,我认为(在这里不太了解)在某些系统上确实是一件好事,因为在跟踪分配的内存块时会产生开销。

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

typedef struct {
    unsigned int sizeX;
    unsigned int sizeY;
    int **cell;
    int *data; /* FOR INTERNAL USE ONLY */
} matrix;

matrix * matrix_malloc(unsigned int, unsigned int);
void matrix_free(matrix *);
void matrix_zero(matrix *);
void matrix_print(matrix *);

int
main(int argc, char *argv[])
{
    int y, x;
    matrix  *theMatrix = NULL;

    if (argc != 3) {
        fprintf(stderr, "usage: %s sizeX sizeY\n", argv[0]);
        return 1;
    }

    x = atoi(argv[1]);
    y = atoi(argv[2]);

    if (x < 10 || y < 10) {
        fprintf(stderr, "usage: sizeX and sizeY must be >= 10\n");
        return 1;
    }

    if ((theMatrix = matrix_malloc(x, y)) == NULL)
        return 1;

    matrix_zero(theMatrix);
    /* lots of modification of the contents of the matrix would happen here */
    matrix_print(theMatrix);

    matrix_free(theMatrix);

    return 0;
}

matrix *
matrix_malloc(unsigned int sizeX, unsigned int sizeY)
{
    int i;
    matrix  *mat;

    if ((mat = malloc(sizeof(matrix))) == NULL) {
        return NULL;
    }

    if ((mat->data = malloc(sizeX * sizeY * sizeof(int))) == NULL) {
        free(mat);
        mat = NULL;
        return NULL;
    }
    if ((mat->cell = malloc(sizeX * sizeof(int *))) == NULL) {
        free(mat->data);
        free(mat);
        mat = NULL;
        return NULL;
    }
    mat->sizeX = sizeX;
    mat->sizeY = sizeY;
    for (i = 0; i < sizeX; i++) {
        mat->cell[i] = mat->data + mat->sizeX * i;
    }

    return mat;
}

void
matrix_free(matrix *mat) {
    free(mat->cell);
    free(mat->data);
    free(mat);
    mat = NULL;
}

void
matrix_zero(matrix *mat)
{
    memset(mat->data, 0, mat->sizeX * mat->sizeY * sizeof(int));
}

void
matrix_print(matrix *mat)
{
    unsigned int    x, y;

    for (x = 0; x < mat->sizeX; x++) {
        for (y = 0; y < mat->sizeY; y++)
            printf("%d ", mat->cell[x][y]);
        printf("\n");
    }
}

当我以./a.out 10 10运行上述程序时,没有问题,但是当我指定30 20而不是10 10时,遇到了一些问题。

在MacOSX(10.6.7)上,我得到:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 540024880 540024880 540024880 540024880 540024880 808465461 943207474 875896880 875704368 540031032 
842216505 926168880 926425140 909719605 540031032 926234424 909325360 875896888 825438256 540160816 10 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

然后它正确退出。

在OpenBSD(4.7)上,我可以做到这一点:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

然后它只是段错误

我最初的想法是,当分配足够大的内存块以使其跨越页面边界时,这只是一个问题,但是当我使用50 50作为大小时,它运行良好。

我已经将其缩小到目前的范围,并尝试使用Google搜索(虽然不太确定我应该搜索的是:|),并询问了我的几个朋友,但这使他们都陷入了困境。

我发现了C. Segmentation Fault,当函数 用C中的指针 修改动态分配的2d数组 int矩阵时-内存分配混乱,但它们并不相关(据我所知)。

如果有人可以指出正确的方向,或者指出问题或指向一些相关的文档,我将不胜感激。

for (i = 0; i < sizeX; i++) {
        mat->cell[i] = mat->data + mat->sizeX * i;
    }

这些SizeX之一必须是sizeY。

for (i = 0; i < sizeX; i++) {
    mat->cell[i] = mat->data + mat->sizeX * i;
}

想象一下,如果sizeX是100,sizeY是2。在这里,您要布局sizeX行,其中100行,每个sizeX整数,其中100行。 哎呀

mat->sizeX应该是mat->sizeY 您有sizeX行,每行中都有sizeY个元素。 因此,您需要跳过正向的sizeY整数才能到达下一行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM