char缓冲区和struct中的3x int

时间:2014-08-14 14:41:17

标签: c linux struct

我正在使用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;
}

3 个答案:

答案 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

您可以选择:

  • 静态内存(重入和并发问题)
  • 动态记忆(mallocfree
  • 来电者提供的内存(例如,返回结构本身而不是指向它的指针)

答案 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;