【问题标题】:Segmentation fault when blurring an images matrix. [C]模糊图像矩阵时出现分割错误。 [C]
【发布时间】:2017-12-02 23:11:51
【问题描述】:

这是我的程序所做的简化版本,我的程序旨在从高度图创建随机地形。这就是我创建高度图的方式。

我已经通过 gdb 运行了它,但是当我通过 gdb 运行它时,它永远不会出现 seg 错误。当我正常运行它时,它会出现段错误。我不知道为什么,它不应该以同样的方式工作。有没有一种工具可以用来可视化我的程序的内存使用情况?

我正在尝试模糊可以访问像素值的矩阵。矩阵逐列索引。

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <time.h>

#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))

typedef struct {
    int width;
    int height;
    double ** mat;
} grid_t;

static double r2()
{
    return (double)rand() / (double)RAND_MAX ;
}

grid_t * create_grid(int width, int height) {
    grid_t * grid = malloc(sizeof(grid));
    grid->width = width;
    grid->height = height;
    grid->mat = malloc(height*sizeof(double *));
    int i = 0;
    for(; i < height; i++){
        grid->mat[i] = malloc(width*sizeof(double));
    }
    return grid;
}

grid_t * clone_grid(grid_t * grid) {
    grid_t * clone = create_grid(grid->width, grid->height);
    int i = 0;
    for(; i < clone->height; i++){
        int j = 0;
        for(; j < clone->width; j++){
            clone->mat[i][j] = grid->mat[i][j];
        }
    }
    return clone;
}

void init_rand(grid_t * grid) {
    int i = 0;
    for(; i < grid->height; i++) {
        int j = 0;
        for(; j < grid->width; j++) {
            //srand(time(NULL) + rand()%time(NULL)); uncomment this for the weird effect.
            grid->mat[i][j] = r2();
        }
    }
}


void free_grid(grid_t * grid) {
    int i = 0;
    for(; i < grid->height; i++) {
        free(grid->mat[i]);
    }
    free(grid->mat);
}

void blur_grid(grid_t * grid, int radius) {
    printf("blurring...");
    grid_t * clone = clone_grid(grid);
    int i, j, x, y;
    for(i = 0; i < grid->height; i++) {
        int x_min = MAX(0, i-radius), x_max = MIN(clone->height, i+radius);
        for(j = 0; j < grid->width; j++) {
            int y_min = MAX(0, j-radius), y_max = MIN(clone->width, j+radius);
            unsigned int sum = 0;
            int count = 0;
            for(x = x_min; x < x_max; x++){
                for(y = y_min; y < y_max; y++){
                    sum += clone->mat[x][y];
                    count++;
                }
            }
            grid->mat[i][j] = sum / count;
        }
    }
    printf("blurred\n");
    free_grid(clone);
}

int main() {
    int width = 512;
    int height = 1024;
    int blur_iter = 1;
    int blur_radius = 2;

    grid_t * grid = create_grid(width, height);

    init_rand(grid);

    int i = 0;
    for(; i < blur_iter; i++) {
        blur_grid(grid, blur_radius);
    }

    free_grid(grid);

    return 0;
}

结果应该是一个矩阵,其值趋于全局平均值。

然而,我得到的结果是一个通常全为零的矩阵。

【问题讨论】:

  • 代码应该只声明两个网格,而不是调用 malloc() 和 free()。建议:grid_t originalGrid[ height ][ width ] = {0};' and grid_t blurredGrid[ height ][ width ] = {0};`
  • blur_grid() 函数正在使用“半径”内所有位置的完整值它应该使用周围值的某个百分比,其中百分比越远离目标位置。建议使用目标的 25%、距离 1 个位置的所有 8 个位置的 5% 和距离 2 个位置的所有 16 个位置的 2.5%。

标签: c segmentation-fault malloc


【解决方案1】:

你在模糊中的问题是你的 sum 变量是 unsigned int 类型,但应该是双精度的。 此外,您正在进行整数除法。

unsigned int sum = 0;

应该是

double sum = 0;

下一个问题是这一行:

grid_t * grid = malloc(sizeof(grid));

您分配了 grid_t* 的大小,但应该分配 grid_t 的大小。
这一行应该是

grid_t * grid = malloc(sizeof(grid_t));


为了完整起见,您还需要释放指向网格本身的指针:

free_grid(grid);
free(grid);

模糊中的克隆也是如此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多