繁体   English   中英

C中二维数组的分割错误

[英]Segmentation Fault on 2D array in C

我正在制作所谓的完整图像,但是我有一个问题。 当我达到一定数量时,我会遇到细分错误。 图像大小为273 * 273,274 * 274不工作。 所以我试图Malloc我的双数组。 相同。 我读过一个函数中的数组在堆栈中,并且堆栈的空间很小。 如何使我的数组在内存中声明?

我正在使用C99和SDL:

void integral_img(SDL_Surface * img)
{
    int **M;

    M = malloc(img->w * sizeof(int *));
    for (int i = 0; i < img->w; i++)
    {
        M[i] = malloc(img->h * sizeof(int));
    }
    int sum_int = 0;
    Uint8 sum = 0;

    for (int i = 0; i < img->h; i++)
    {
        for (int j = 0; j < img->w; j++)
        {
            SDL_GetRGB(getpixel(img, i, j), img->format, &sum, &sum, &sum);

            if (i == 0 && j == 0)
                sum_int = (int)sum;
            if (i == 0 && j > 0)
                sum_int = (int)sum + M[i][j - 1];
            if (j == 0 && i > 0)
                sum_int = (int)sum + M[i - 1][j];
            if (i > 0 && j > 0)
                sum_int = (int)sum + M[i - 1][j] + M[i][j - 1] - M[i - 1][j - 1];
            M[i][j] = sum_int;
        }
    }
}
  • 您正在分配基于指针的查找表,而不是2D数组。 它将起作用,但是它是广泛的不正确的做法:它使程序不必要地变慢而毫无收获。 考虑改用2D数组:

     int (*M)[w] = malloc( sizeof(int[h][w]) ); ... free(M); 
  • 一个错误在这里:

     M = malloc(img->w * sizeof(int *)); for (int i = 0; i < img->w; i++) { M[i] = malloc(img->h * sizeof(int)); } 

    在这里,您将查找表的最内部尺寸声明为w ,width。

    但是后来

     for (int i = 0; i < img->h; i++) { for (int j = 0; j < img->w; j++) ... M[i][j] = sum_int; 

    您说最里面的尺寸是h ,height。

  • 此外,由于您不会在任何地方释放内存,因此每次调用该函数时,程序都会泄漏大量内存。 实际上,您似乎在填满查询表后甚至没有使用它。

代码的简化版本,经过修改以说明2D数组的初始化清除(您必须释放malloc的内容):

简而言之,数组初始化必须遵循为rowcolumn创建内存的方式:

typedef struct  {
    int h;
    int w;
}SDL_Surface;
//if you change your prototype to pass the initializer then you can
//free it in the calling function.  Otherwise, as written in your OP
//you will have a memory leak.
void integral_img(SDL_Surface * img, int **m);

int main(int argc, char* argv[])
{
    SDL_Surface img;
    int **M; 

    img.h = 100;
    img.w = 50;
    //create memory for array in calling function
    M = malloc(img.w * sizeof(int *));
    if(!M){ /*handle error and leave*/ }//test results of malloc
    for (int i = 0; i < img.w; i++)//... If you create space for w rows and h columns...
    {
        M[i] = malloc(img.h * sizeof(int));// note modified prototype
        if(!M[i]) {/*handle error and leave*/} //test results of malloc
    }

    integral_img(&img, M);

    //use img...

    //free M :(no memory leaks)

    for (int i = 0; i < img.w; i++)
    {
        if(M[i]) free(M[i]);
    }
    if(M) free(M);


    return 0;
}

void integral_img(SDL_Surface * img, int **m)
{


    for (int i = 0; i < img->w; i++)//... Then you must access w rows and h columns
    {                               // (w & h were reversed in your code)
        for (int j = 0; j < img->h; j++)
        {
            m[i][j] = (i+1)*(j+1);
        }
    }
}

我不认为您的代码是伪造的,但我怀疑这行:

SDL_GetRGB(getpixel(img, i, j), img->format, &sum, &sum, &sum);

无论如何,为什么您必须以这种方式分配2D数组? 为什么不止一个继续阻塞?

看一下我的代码:

void integral_img(SDL_Surface * img)
{
    #define _IDX(x,y) ((x)+((y)*cx))
   int cx=img->w,
        cy=img->h;
    int *M;

    //allocating only one continues block of memory
    M = malloc(cx*cy * sizeof(int ));
    if(!M){
        perror("not enough memory");
        exit(1);
    }

    int sum_int = 0;
    Uint8 t sum = 0;

    for (int i = 0; i < cy; i++)
    {
        for (int j = 0; j < cx; j++)
        {
            SDL_GetRGB(getpixel(img, i, j), img->format, &sum, &sum, &sum);

            if (i == 0 && j == 0)
                sum_int = (int)sum;
            if (i == 0 && j > 0)
                sum_int = (int)sum + M[_IDX(i,j - 1)];
            if (j == 0 && i > 0)
                sum_int = (int)sum + M[_IDX(i- 1,j )];
            if (i > 0 && j > 0)
                sum_int = (int)sum + M[_IDX(i- 1,j )] + M[_IDX(i,j - 1)] - M[_IDX(i- 1,j - 1)];
            M[_IDX(i,j )] = sum_int;
        }
    }

    // easy to free
    free(M); 
    return;
}

它更干净,并且在分配和释放内存上使用的迭代次数更少。

暂无
暂无

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

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