0

我正在开发一个应该处理表单的 PGM 图像文件的程序

P2
24 7
11
0  0   0   0   0   0  0   0  0  0  0   0   0  0   0   0   0  0  0  0  0  0  0  0
0  11  11  11  11  0  11  0  0  0  11  0   0  11  0   0   0  11  0  0  0  11  0  0
0  11  0   0   0   0  11  0  0  0  11  0   11  0  11  0   0  11  11 0  0  11  0  0
0  11  11  11  11  0  0  11  0  11  0  0   11  11 11  0   0  11  0  11 0  11  0  0
0  11  0   0   0   0  0  11  0  11  0  11  0  0   0   11  0  11  0  0  11 11  0  0
0  11  11  11  11  0  0  0  11  0   0  11  0  0   0   11  0  11  0  0  0  11  0  0
0  0   0   0   0   0  0  0  0   0   0  0   0  0   0   0   0  0  0  0  0  0  0  0
7  7   7   7   7   7  7  7  7   7   7  7   7  7   7   7   7  7  7  7  7  7  7  7

我有以下结构来保存数据和初始化函数

struct Image {
    int row, column;
    int maxValue;
    unsigned int data[MAXLINELENGTH];
}

 Image * Image_Init ()
{
     Image tmp_Image;
     tmp_Image.row = 0;
     tmp_Image.column = 0;
     int i;
     for (i = 0; i < MAXLINELENGTH; i++)
     {
        tmp_Image.data[i] = 0;
     }
     return &tmp_Image;
}

它给了我一个警告,说该函数返回一个局部变量的地址。我想要做的基本上是创建一个对象图像,并通过它。我该怎么做呢?

谢谢你

编辑====================================

我似乎可以使用

 Image * Image_Init ()
{
     Image *tmp_Image;
     tmp_Image->row = 0;
     tmp_Image->column = 0;
     int i;
     for (i = 0; i < MAXLINELENGTH; i++)
     {
        tmp_Image->data[i] = 0;
     }
     return tmp_Image;
}

现在我遇到了需要从数组中读取数据的问题。我使用相同的基本结构

Image * Image_Init_From_Array (unsigned int height, unsigned int width, unsigned int *data)
{
    Image *tmp_Image;
    tmp_Image->row = width;
    tmp_Image->column = height;
    tmp_Image->maxValue = 255;
    int i;
    for (i = 0; i < MAXLINELENGTH; i++)
    {
        tmp_Image->data[i] = data[i];
    }
    return tmp_Image;
}

这编译得很好,但会导致分段错误。

4

3 回答 3

1

您编辑的函数为指向 的指针分配内存Image,但不为Image变量分配内存。

您对 LostBoy 的回答的评论说您必须遵守给定的签名:

Image *i1; 
i1 = Image_Init_From_Array(10, 20, hi);

这意味着Image_Init_From_Array()必须自己分配内存。您不能只Image在函数中创建一个变量,因为该变量的内存将在退出函数时再次被释放。

这种情况是malloc().

  • 为函数Image中的对象分配内存Image_Init_From_Array()
  • 返回指向新创建对象的指针
  • 将该指针传递给需要该对象的其他函数
  • 编写一个Image_delete(Image *)函数,在其中释放之前由malloc(). 如果你不这样做,你就会有内存泄漏。
于 2013-09-24T08:21:22.923 回答
1

只需传入一个指向图像的指针:

Image * Image_Init (Image * i)

然后填写那个。然后,您可以返回指针或使用调用函数中传递的指针指向的变量:

基本上:

  Image * Image_Init (Image *tmp_Image)
 {

      tmp_Image->row = 0;
      tmp_Image->column = 0;
      int i;
      for (i = 0; i < MAXLINELENGTH; i++)
      {
         tmp_Image->data[i] = 0;
      }
      return tmp_Image;
 }

 void caller()
 {
     Image img;

     Image_Init(&img);

     // work with img here
  }

对于编辑部分: tmp_Image 当时是一个野指针,指向任何地方并访问该内存将导致 SEGFAULT。尤其是在要操作现有“对象”的此函数中,您需要将结构作为指针传递:

Image * Image_Init_From_Array (Image * image, unsigned int height, unsigned int width, unsigned int *data)
{
...
}
于 2013-09-24T07:20:00.400 回答
1

如果您需要通过指针传递结构,则需要将其分配到某个地方。您可以静态或自动分配它并将指针传递给较低的范围(不能传递高于其范围的指针)。

my_function() {
    Image tmp_image;
    Image_init(&tmp_image);
    //...
}

或者全局分配,取一个地址:

Image tmp_image;

my_function() {
    Image_init(&tmp_image);
    //...
}

或者动态分配:

my_function() {
    Image *tmp_image;
    tmp_image = malloc(sizeof(Image));
    Image_init(tmp_image);  // this time it's already a pointer, so no '&'
    //...
}

如果您动态分配,则不需要为小图像提供所有额外空间。相反,在分配之前计算您需要的空间。您可能希望将分配和初始化的功能结合起来,并制作一个构造函数来一步完成分配和初始化:

typedef struct {
    int row, column;
    int maxValue;
    unsigned int data[];  //C99 allows this empty array to do the "struct hack"
} Image;

Image *new_Image (int row, int column, int max) {
    Image *tmp = malloc(sizeof(Image) + row*column);
    if (tmp != NULL) {
        tmp->row = row;
        tmp->column = column;
        tmp->maxValue = max;
    }
    return tmp;
}

对于 ANSI C,您必须1为数据数组的大小加上一个,然后1从大小计算中减去。您还可以将数据字段声明为指针并单独分配它,或者像这里一样sizeof(Image) + row*columns- 作为一个块 - 但您也需要设置指针。

于 2013-09-24T07:15:17.723 回答