float类型创建对象C ++后缓冲区内容丢失

时间:2016-11-03 13:08:36

标签: c++ buffer typedef

我有一个包含浮点类型缓冲区的类,它指向一个RGB值数组。缓冲区是正确创建和存储的,但是当我通过函数将此类的实例返回到 main()时,缓冲区的内存是不可读的。这是初始类

namespace imaging
{
    typedef float component_t;

    class Image
    {
        protected:
            component_t * buffer;
            unsigned int width, height;
        public:
            Image(unsigned int width, unsigned int height, const component_t * data_ptr) {
            this->width = width;
            this->height = height;
            this->setData(data_ptr);
            this->buffer = const_cast<component_t *>(data_ptr);
        }

        component_t getRedValPixel(unsigned int x, unsigned int y) const {
            int pos = x * this->width * 3;
            component_t red;
            red = this->buffer[pos];
            return r;
        }
    }
}

要创建此类的实例,我使用 readImage(char * filepath)方法,在加载数据后,该返回语句:

return &Image(width, height, buffer);

以下是 main()函数中的代码:

Image* image = readIamge(filepath);
int width = image->getWidth(); //retrieves it correctly
int height = image->getHeight(); //retrieves it correctly
for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
        cout << image->getRedValPixel(i,j);
    }
}

2 个答案:

答案 0 :(得分:4)

让我们仔细看看你的退货声明:

return &Image(width, height, buffer);

执行Image(...)时会发生什么,即创建临时对象。一旦它的表达式结束,该临时对象将被破坏。然后返回一个指向此临时对象的指针,该对象随后将立即消失,并为您指向一个不存在的对象。尝试取消引用此指针将导致未定义的行为

您从文件中读取的数据可能仍然存在于内存中,但是您返回的指针无法使用它。

我建议您通过值返回对象,并研究移动语义移动构造函数the rules of three, five and zero之类的内容。我还建议您不仅要将指针复制到对象的实际数据,还要复制实际数据本身(深层复制)。

答案 1 :(得分:1)

返回&amp;图像(宽度,高度,缓冲区);将返回堆栈中本地创建的对象的地址,该地址将在丢失范围(即返回语句)后被销毁。

解决方案是在堆中分配Image对象。 E.g。

main()
{
....
Image* image = NULL;
readImage(filepath, image );
int width = image->getWidth(); //retrieves it correctly
int height = image->getHeight(); //retrieves it correctly
for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
        cout << image->getRedValPixel(i,j);
    }
}
delete image;
image = NULL
...
}


void readImage(char* filepath, Image* o_pBuffer ) 
{
   .....
   o_pBuffer = new Image(width, height, buffer);
   return o_pBuffer;
}

main()
{
....
Image* image = NULL;
image = readImage(filepath );
int width = image->getWidth(); //retrieves it correctly
int height = image->getHeight(); //retrieves it correctly
for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
        cout << image->getRedValPixel(i,j);
    }
}
delete image;
image = NULL
...
}


Image* readImage(char* filepath ) 
{
   .....
   Image* o_pBuffer = new Image(width, height, buffer);
   return o_pBuffer;
}