将 int 成员添加到 C 结构会导致段错误
我仍在学习 C,并开始使用它来生成图像。 我不明白为什么我的一个程序会出现段错误。 这是源代码,减少到 40 行:
#include <stdio.h>
#include <stdlib.h>
struct color {
unsigned char r, g, b;
};
struct image {
int w, h/*, o*/;
struct color **data;
};
int main() {
// Declarations
int x, y;
struct color *black;
struct image *img;
// Set up color black
black = (struct color *) malloc(sizeof(struct color *));
black->r = 0;
black->g = 0;
black->b = 0;
// Set up image img
img = (struct image *) malloc(sizeof(struct image *));
img->w = 1;
img->h = 1;
/*img->o = 0;*/
img->data = (struct color **) malloc(img->h * sizeof(struct color *));
for (y = 0; y < img->h; y++) {
img->data[y] = (struct color *) malloc(img->w * sizeof(struct color));
}
// Fill in img with black
for (x = 0; x < img->w; x++) {
for (y = 0; y < img->h; y++) {
img->data[y][x].r = black->r;
img->data[y][x].g = black->g;
img->data[y][x].b = black->b;
}
}
// Free black
free(black);
// Free img
for (y = 0; y < img->h; y++)
free(img->data[y]);
free(img->data); // Segfaults
free(img); // Also segfaults
return 0;
}
它编译并运行良好(在 Ubuntu 上使用 gcc,在 Vista 上使用 Cygwin),但是取消注释处理 img->o 的两行会破坏它。 我有一种感觉,它与 上一个问题有关,但我正在 malloc'ing一切需要进行 malloc 的东西(我认为)。 任何帮助,将不胜感激。
I'm still learning C, and have started using it to generate images. I can't figure out why one of my programs is segfaulting. Here's the source code, cut down to 40 lines:
#include <stdio.h>
#include <stdlib.h>
struct color {
unsigned char r, g, b;
};
struct image {
int w, h/*, o*/;
struct color **data;
};
int main() {
// Declarations
int x, y;
struct color *black;
struct image *img;
// Set up color black
black = (struct color *) malloc(sizeof(struct color *));
black->r = 0;
black->g = 0;
black->b = 0;
// Set up image img
img = (struct image *) malloc(sizeof(struct image *));
img->w = 1;
img->h = 1;
/*img->o = 0;*/
img->data = (struct color **) malloc(img->h * sizeof(struct color *));
for (y = 0; y < img->h; y++) {
img->data[y] = (struct color *) malloc(img->w * sizeof(struct color));
}
// Fill in img with black
for (x = 0; x < img->w; x++) {
for (y = 0; y < img->h; y++) {
img->data[y][x].r = black->r;
img->data[y][x].g = black->g;
img->data[y][x].b = black->b;
}
}
// Free black
free(black);
// Free img
for (y = 0; y < img->h; y++)
free(img->data[y]);
free(img->data); // Segfaults
free(img); // Also segfaults
return 0;
}
It compiles and runs fine (using gcc on Ubuntu and on Vista with Cygwin), but uncommenting the two lines dealing with img->o breaks it. I have a feeling it's related to this previous question, but I'm malloc'ing everything that needs to be malloc'ed (I think). Any help would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您的 malloc 语句中有一个错误。 您正在分配指针而不是结构。 这仅提供 4 个字节的内存,而不是结构所需的实际大小。
为指针分配内存时,您需要为所指向的对象分配内存,而不是指针的类型。 如果您只是如图所示编写
sizeof(*black)
,即使black
的类型发生变化,您也将始终获得正确的类型。There is a bug in your malloc statements. You are mallocing a pointer and not a struct. This gives you only 4 bytes of memory instead of the actual size required by your struct.
When allocating memory for a pointer, you need to allocate memory for the thing being pointed at, not the type of the pointer. If you simply write
sizeof(*black)
as shown, you will always get the right type, even if the type ofblack
changes.乍一看,您似乎使用了额外级别的指针间接寻址,这导致了段错误。 当您分配内存时,它是指向对象的指针,而不是指向对象指针的指针。 所以你将拥有:
At first glance, it seems that you're using an additional level of pointer indirection, and that's causing the segfault. When you malloc memory, it's a pointer to the object, not a pointer to a pointer to an object. So you'll have:
JaredPar 有正确的答案,但如果出现段错误,首先要做的就是在 valgrind 下运行程序。 对于处理此类问题有很大的帮助。
顺便说一句,我已经在这个错误上浪费了好几天的时间。 很高兴你在 C 编程职业生涯的早期就遇到了它,并且将来会一直留意它。
JaredPar has the right answer, but if you get a segfault, the first thing to do is run the program under valgrind. It is a huge help for dealing with problems like this.
BTW, I've wasted days on that exact bug. Be happy you ran into it early in your C programming career and will always watch out for it in the future.
哎呀,代码被截断了; 我忘记转义小于号。 这里是:
Oops, the code was cut off; I forgot to escape a less-than sign. Here it is: