我真的非常感谢那些给我帮助的人。谢谢!
struct MyImage
{
BYTE* pImage;
int width;
int heigth;
};
MyImage* pMyImage = new MyImage;
pMyImage->pImage = new BYTE[width * heigth];
我应该这样做吗?
delete [] pMyImage->pImage;
或者我应该这样做?
delete[] pMyImage->pImage;
delete pMyImage;
希望你的想法和谢谢。
MyImage* transform(Bitmap &gdiImage)
{
MyImage* image=new MyImage;//新建一个MyImage
int height=gdiImage.GetHeight();
int width=gdiImage.GetWidth();
image->pImage=new BYTE[height*width];//为存储灰度图像数据分配内存
image->height=height;
image->width=width;
Color temp;
for(int y = 0;y < height; ++y)
for(int x = 0;x < width; ++x)
{
//获取当前GDI+图像坐标所指向的像素的颜色
gdiImage.GetPixel(x, y, &temp);
//将这个像素的灰度值赋给灰度图像对应的内存中的相应的字节
*(image->pImage + y * width + x) = transformPixel(temp.GetValue());
}
return image;
}
我的代码如下,此函数将gdiImage转换为结构MyImage。 作为一个firend说,如下,我不能新的MyImage和新的pImage,MyImage的元素。 我该怎么办?谢谢
答案 0 :(得分:6)
你的第二种选择是正确的,但为了避免你首先调用delete
(例如忘记这样做)错误,我建议使用适当的工具来处理这个问题。
例如,您的动态分配的BYTE
数组可能是std::vector
的良好候选者。 MyWidget
可以由某种智能指针管理,例如std::unique_ptr
或std::shared_ptr
等。或者你甚至可能根本不需要动态分配它,但可以在堆栈上创建它,然后在需要时传递地址。所以,也许是这样的:
// An example function dealing with images. This one draws it.
void draw(MyImage *img);
struct MyImage
{
std::vector<BYTE> image;
int width;
int heigth;
};
MyImage myImage;
myImage.image.resize(width * height);
// ...
draw(&myImage);
答案 1 :(得分:3)
你的第二个选择是好的:
delete[] pMyImage->pImage;
delete pMyImage;
new
必须始终与delete
匹配,而new[]
必须始终与delete[]
匹配。
MyImage
应负责分配/释放此数据以防止出现任何错误......
您可以将delete[] pMyImage->pImage;
放在MyImage
析构函数中:
MyImage::~MyImage()
{
delete [] pImage;
}
最后,我建议你看看c ++中的智能指针。例如std::unique_ptr
:
当发生以下任何一种情况时,对象被销毁并释放其内存:
- unique_ptr管理对象被销毁
- unique_ptr管理对象通过operator =()或reset()分配另一个指针。
通过调用Deleter(ptr),使用潜在的用户提供的删除器销毁对象。删除器调用对象的析构函数并分配内存。
类似的东西:
#include <memory>
struct MyImage
{
std::unique_ptr<BYTE[]> m_Image;
int width;
int heigth;
};
MyImage* pMyImage = new MyImage;
pMyImage->m_Image= std::unique_ptr<BYTE[]>( new BYTE[ width * height ] );
答案 2 :(得分:1)
正确的是
delete[] pMyImage->pImage;
delete pMyImage;
您必须将new
与delete
匹配,将new[]
与delete[]
匹配(除少数例外,例如,当您知道某个库处理内存本身时,像Qt及其父/子系统一样)
答案 3 :(得分:1)
第二个。您使用new
或new[]
手动分配的任何内存都必须分别使用delete
或delete[]
手动取消分配。
答案 4 :(得分:-1)
我在MyImage中实现了构造函数和析构函数:
struct MyImage
{
MyImage() : pImage(nullptr), width(0), height(0)
{
}
~MyImage()
{
delete [] pImage;
}
BYTE* pImage;
int width;
int heigth;
};
一般来说,最好将pImage,width和height作为私有成员。