我有一个包含浮点类型缓冲区的类,它指向一个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);
}
}
答案 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;
}