C++ 什么';这是使用C++;具有函数的新运算符?
这是一个长的。我有一个从磁盘加载一些图像数据的函数。我尝试过三种不同的方法,其中一种不起作用,我想知道最聪明的方法是什么 方法1: 我曾经对它进行过设置,以便加载的数据是函数的参数,这似乎需要在函数外部为它分配空间,然后向分配的空间传递指针。这需要提前知道图像的大小,因此必须先使用辅助函数来获得图像的宽度和高度。下面是一个例子 优点:在调用代码中更明确地表示正在分配内存,因此应该删除 缺点:需要提前知道图像大小C++ 什么';这是使用C++;具有函数的新运算符?,c++,function,scope,new-operator,C++,Function,Scope,New Operator,这是一个长的。我有一个从磁盘加载一些图像数据的函数。我尝试过三种不同的方法,其中一种不起作用,我想知道最聪明的方法是什么 方法1: 我曾经对它进行过设置,以便加载的数据是函数的参数,这似乎需要在函数外部为它分配空间,然后向分配的空间传递指针。这需要提前知道图像的大小,因此必须先使用辅助函数来获得图像的宽度和高度。下面是一个例子 优点:在调用代码中更明确地表示正在分配内存,因此应该删除 缺点:需要提前知道图像大小 // Data allocated outside the image, alloc
// Data allocated outside the image, allocated space passed to function. This works.
// Notice that width & height are passed to the function.
size=(*width)*(*height);
image = new unsigned char[size];
void read_pgm(unsigned char *image, char *file_name, int width, int height){
// Code to read sizeof(char)*width*height bytes of data from the file into image
}
方法2:
我认为让函数分配自己的数据会很好,这样我就不需要传递它的大小。如果我试图在函数中为它分配空间,它似乎在函数结束后丢失了。在下面的例子中,函数read_pgm
运行良好,但是如果我试图将该数据写入另一个文件,我的代码就会崩溃
优点:不需要提前知道图像大小,不需要在调用代码中分配数据
缺点:不起作用。另外,如果是这样的话,如果我没有清除函数外部的映像,在循环中重复调用它会导致内存泄漏吗
// Data allocated inside the image for a pointer passed to the function. This doesn't work.
void read_pgm(unsigned char *image, char *file_name, int *width, int *height){
size=(*width)*(*height);
image = new unsigned char[size];
// Code to read the data from the file into image
}
方法3:
在这里,数据再次在函数中分配,但作为返回项返回。这是可行的,也就是说,我可以将数据写入另一个图像。我不明白为什么这是可行的,而方法2却不行
优点:与方法2相同
缺点:与方法2相同,只是目前有效
// Data allocated in the function, and returned. This works.
unsigned char* read_pgm(char *file_name, int *width, int *height){
// Allocate data for the image
size=(*width)*(*height);
image = new unsigned char[size];
// Code to read the data from the file into image
return image; // Return pointer to the data
}
因此,我的问题是:
unsigned char * & image
否则,您将分配内存,并且传递的指针的副本将指向它。原始指针对象不会更改
对问题1的答复
听说过吗
智能指针可以用来自行操作内存。如果你不想出于某种莫名其妙的原因使用智能指针,比如伪优化,那么我认为你自己描述了所有方法的优缺点——总是有权衡的。由您决定方法2不起作用,因为您正在按值传递指针,并在本地覆盖该值,因此函数外部指针的值不会更改。您可以通过引用或通过向指针传递指针来修复此问题 至于另一个问题:这实际上只是一个明确记录谁有责任删除分配的数据的问题。(顺便说一下:是的,你应该解除分配,否则你会泄漏)。在许多API中,您将在文档中看到:“调用者有责任删除此函数”或“调用其他函数删除分配的数据” 消除这种所有权顾虑的一个好方法是使用智能指针(正如Armen所建议的)。“2.为什么方法2不起作用?” 因为您是通过副本而不是引用传递指针。您传入一个指针,然后使用
new
调用迅速重新初始化该指针指向的位置。当达到函数的范围时,局部变量image
的寿命也就达到了,所有可爱的新存储都到哪里去了
您真正想要做的(在本例中)是传递对指针的引用或指向指针的指针,以便可以更改所传递参数的值(本例中为指针),并使该更改在函数范围之外可见
void read_pgm(unsigned char **image, char *file_name, int *width, int *height)
{
size=(*width)*(*height);
(*image) = new unsigned char[size];
// Code to read the data from the file into image
}
如果你想知道聪明的方法,那么答案必须是“以上都没有”。聪明的方法?使用向量。这就是它的目的。因为直接使用
new
很糟糕。管理你自己的记忆范围很糟糕。我们有这方面的课程。和字符串的char*
?至少将其设置为常量字符*
<代码>常量标准::字符串&更好。我还必须问-你试图读取的图像格式是什么,它不以文件格式存储图像的宽度和高度?在我看来,你最好还是从文件中读出来
std::vector<unsigned int> void ReadImage(const std::string& filename, int width, int height) {
std::vector<unsigned int> imageData(width * height);
// Read here from filestream
}
std::vector<unsigned int> imageData = ReadImage("ohai.png", 1000, 600);
std::vector void ReadImage(常量std::字符串和文件名、整型宽度、整型高度){
std::矢量图像数据(宽度*高度);
//阅读这里的文件流
}
std::vector imageData=ReadImage(“ohai.png”,1000600);
您需要了解-const correction、RAII和标准库。您当前所做的一切都会导致内存泄漏,因为您从未删除任何内容 首先,是的,使尺寸可变。第二,返回指向新分配的堆存储的指针并记住在调用者中删除它,或者返回智能容器对象 一个
std::vector
会很好地:
std::vector<unsigned char> get_image(const std::string & filename, size_t & width, size_t & height)
{
// determine width and height
/* ... */
std::vector<unsigned char> result(width * height, 0);
// read into &result[0], vector guarantees contiguous storage
return result;
}
std::vector get\u image(常量std::字符串和文件名、大小和宽度、大小和高度)
{
//确定宽度和高度
/* ... */
标准::矢量结果(宽度*高度,0);
//读入结果[0],向量保证连续存储(&R)
返回结果;
}
事实上,这本书中有一个关于这些问题的非常好的章节
正如您所说,最大的问题是确保内存的分配方式不会泄漏。C++有很多便利的工具来做,这是最明显的。
{
MyData *md = new MyData(args);
doSomething(md);
}