我正在使用C(& Java)和一个基准测试进行一些测试。我已经获得了图像变形的代码(从我的第一个答案),我正在将其重写为C.我想比较速度。我已经完成了简单的图像"编解码器" - 使用某些方法存储没有压缩的颜色,RGB(或BGR?)和称为OneArrayImage(ArrayImage = OneArrayImage *)的结构,并且存在错误。 当我尝试使用char *和3x整数创建struct的实例时,这些数据被破坏(例如,w = 0,len = -24562 ......)。我该如何调整这个结构和方法(ArrayImage image(4)和ArrayImage image_empty(2))才能工作?感谢。
(2个主要来源:)
Image.c:http://pastebin.com/c0ZmuRbU
Deformer.c:http://pastebin.com/kCbkGSzm
错误可能在:
struct OneArrayImage {
int* w;
int* h;
int* len;
unsigned char* pix;
};
typedef struct OneArrayImage* ArrayImage;
/*** Prepare ***/
/*** New ***/
ArrayImage image(char* pix, int len, int w, int h) {
if(w < 1 || h < 1 || len < 1 || pix == NULL) {
return NULL;
}
int len2 = (w * h * 3);
if(len2 > len) {
return NULL;
}
struct OneArrayImage img = {&w, &h, &len2, pix};
ArrayImage ret = &img;
return ret;
}
ArrayImage image_empty(int w, int h) {
if(w < 1 || h < 1) {
return NULL;
}
int len = (w * h * 3);
unsigned char* pix = (unsigned char*) malloc(len);
struct OneArrayImage img;// = {&w, &h, &len, pix};
img.w = &w;
img.h = &h;
img.len = &len;
img.pix = pix;
ArrayImage ret = &img;
return ret;
}
main()在Deformer.c中,输出:
Starting!
S I : 830835 0
PIX : NOT_NULL
IMG L: NOT_NULL
IMG E: NOT_NULL
PIX L: NULL
PIX E: NULL
正在使用编辑
/*** Typedef ***/
struct OneArrayImage {
int w;
int h;
int len;
unsigned char* pix;
};
typedef struct OneArrayImage* ArrayImage;
/*** Prepare ***/
/*** New ***/
ArrayImage image(char* pix, int w, int h) {
if(w < 1 || h < 1 || pix == NULL) {
return NULL;
}
int len = (w * h * 3);
ArrayImage image = (ArrayImage) malloc(sizeof(struct OneArrayImage));
image->w = w;
image->h = h;
image->len = len;
image->pix = pix;
return image;
}
ArrayImage image_empty(int w, int h) {
if(w < 1 || h < 1) {
return NULL;
}
int len = (w * h * 3);
unsigned char* pix = (unsigned char*) malloc(len);
ArrayImage image = (ArrayImage) malloc(sizeof(struct OneArrayImage));
image->w = w;
image->h = h;
image->len = len;
image->pix = pix;
return image;
}
答案 0 :(得分:3)
您正在返回本地变量的地址。当函数结束时,该变量超出范围,访问其旧地址是非法操作,将触发未定义的行为。
您必须使用malloc()
来分配将保留的堆内存。
另外,我建议反对typedef
:将指针星号放在C中,这非常令人困惑。标量字段(大小)不应该是int *
,它们不是指针!
您应该执行以下操作:
struct OneArrayImage {
int w;
int h;
int len;
unsigned char* pix;
};
struct OneArrayImage * image(char* pix, int len, int w, int h)
{
struct OneArrayImage *img = malloc(sizeof *img);
if(img != NULL)
{
img->w = w;
img->h = h;
img->len = 3 * w * h * len;
img->pix = pix;
}
return img;
}
答案 1 :(得分:1)
struct OneArrayImage {
int* w;
int* h;
int* len;
unsigned char* pix;
};
仔细看结构。您实际上并不想要前三个元素的指针,而是int
值。
当您稍后在代码中遇到错误时,您不正确地分配了自动变量的地址,而不是更正您的类型:
ArrayImage image(char* pix, int len, int w, int h) {
// [...[
struct OneArrayImage img = {&w, &h, &len2, pix};
这些自动变量在函数末尾超出范围,因此你会得到悬空指针,意味着未定义的行为。
顺便说一句:你有与你的返回类型悬挂指针完全相同的问题。请为它分配一些记忆,好吗?
struct OneArrayImage img;
ArrayImage ret = &img;
return ret; // returning a dangling pointer
您可以选择:
malloc
和free
)答案 2 :(得分:1)
您在设计结构时遇到了一个基本问题:
struct OneArrayImage {
int* w;
int* h;
int* len;
unsigned char* pix;
};
宽度,高度和长度变量应该只是int而不是指向int(int *)的指针。之后,当你在这里尝试计算len2时:
int len2 = (w * h * 3);
你实际上是在增加指针。此外,当您设置它们时,您将为它们分配临时存储器的指针:
ArrayImage image(char* pix, int len, int w, int h) {
if(w < 1 || h < 1 || len < 1 || pix == NULL) {
return NULL;
}
int len2 = (w * h * 3);
if(len2 > len) {
return NULL;
}
struct OneArrayImage img = {&w, &h, &len2, pix};
ArrayImage ret = &img;
return ret;
}
最后,在上面,当你返回时,你正在返回一个指向“img”的指针,这很糟糕,因为你也在那里使用临时内存。为了返回指针,您必须分配它(稍后释放它)。例如:
ArrayImage image = (ArrayImage)malloc(sizeof(struct OneArrayImage));
image->w = w;
image->h = h;
image->len = len2;
image->pix = pix;
return image;