C - 将结构写入二维数组会导致分段错误
Posted
技术标签:
【中文标题】C - 将结构写入二维数组会导致分段错误【英文标题】:C - Writing a struct into a 2D array causes Segmentation Fault 【发布时间】:2021-03-19 11:19:02 【问题描述】:我正在尝试编写一个程序,将文本文件读取到结构的二维数组中,但尝试将结构放入该数组会导致程序崩溃。
这是程序
ppm.c
#include "ppm.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
image parse_ascii_image(FILE *fp)
char magic[3];
char comm[1024];
char size[10];
image img;
int height;
int width;
... // some code
pixel **pixelarr;
printf("Commencing internal malloc...\n");
if (height <= 1024 && width <= 1024 && height > 0 && width > 0)
pixelarr = (pixel **) malloc(height * sizeof(pixel*));
else
fprintf(stderr, "Error: Invalid image size: %d * %d", width, height);
return img;
for (int i = 0; i < height; i++)
pixelarr[i] = malloc(width * sizeof(pixel));
int d = 0;
int e;
printf("Filling in array:\n");
for (int row = 0; row < height; row++)
for (int col = 0; col < width; col++)
for (int i = 0; i < 3; i++)
while ((e = fgetc(fp)) != '\n')
d = d * 10;
e = e - 60;
d += e;
if (i == 0)
pixelarr[row][col].red = d;
if (i == 1)
pixelarr[row][col].green = d;
if (i == 2)
pixelarr[row][col].blue = d;
d = 0;
printf("Finished! Copying pixels over: \n");
for (int row = 0; row < height; row++)
for (int col = 0; col < width; col++)
img.pixels[row][col] = pixelarr[row][col];
// ^^^This is where the program crashes
printf("Finished! Freeing internal malloc:\n");
... // some more code
来自 ppm.h 的相关信息:
#ifndef PPM_H
#define PPM_H 1
#include <stdio.h>
...
typedef struct pixel pixel;
struct pixel
int red;
int green;
int blue;
;
typedef struct image image;
struct image
enum ppm_magic magic; // PPM format
char comments[1024]; // All comments truncated to 1023 characters
int width; // image width
int height; // image height
int max_color; // maximum color value
pixel **pixels; // 2D array of pixel structs.
;
...
// Parses an ASCII PPM file.
image parse_ascii_image(FILE *fp);
...
#endif
如果有人可以帮助我找出导致我的程序在那里崩溃的原因,我将不胜感激。 谢谢!
【问题讨论】:
img.pixels
永远不会被初始化。所有似乎都表明您应该简单地用img.pixels = pixelarr;
替换最终的嵌套循环,然后不要释放pixelarr
。这将交给接管返回图像的任何人。您还应该正确初始化img
的所有成员。
关于:enum ppm_magic magic; // PPM format
这是声明特定enum
类型的实例。但是枚举在使用之前从未定义过
关于:struct pixel int red; int green; int blue; ;
像素中的“颜色”每个为 8 位,而不是 int
(4 或 8 字节)
OT:关于; pixelarr = (pixel **) malloc(height * sizeof(pixel*));
和 pixelarr[i] = malloc(width * sizeof(pixel));
1) pixel
的内容未正确定义。 (并且您假设一个像素是 24 位) 2)返回的类型是 void*
可以分配给任何指针。强制转换只会使代码混乱并且容易出错。 3) 始终检查 (!=NULL) 返回值以确保操作成功。如果不成功(==NULL),则通过perror( "malloc failed" );
通知用户,这将向stderr
输出您的错误消息和文本系统错误。
关于:pixelarr[i] = malloc(width * sizeof(pixel));
图像行必须是 4 的倍数(无论可见图像宽度如何),因此该语句可能不足以容纳整行。由于上述原因,这:for (int row = 0; row < height; row++) for (int col = 0; col < width; col++)
很有可能无法访问所有正确的像素
【参考方案1】:
几个问题:1:img.pixels 从未初始化。每当您创建指向某事物的指针而不首先为其分配值时,请尝试将其设置为 NULL 以便更容易调试。请注意,这不会解决问题。要修复它,只需使用结构实例初始化它们。2:您应该释放 pixelarr
。大多数现代操作系统都会这样做,但它仍然是非常非常非常好的做法。3:不使用嵌套循环会不会更容易,而是使用img.pixels = pixelarr
?它实现了相同的效果(除非这是针对一个类,并且这部分是必需的)。
【讨论】:
以上是关于C - 将结构写入二维数组会导致分段错误的主要内容,如果未能解决你的问题,请参考以下文章