- 我有一个从相机中检索图像的函数。
- 此函数有一个名为 GetData() 的函数,该函数返回指向相机创建的图像对象所包含数据的指针。
- GetData() 指向的数据是本地初始化的。
目前,我正在使用 for 循环逐个元素地复制 GetData 指向的数据,但是有没有一种方法可以不使用 for 循环来复制数据?或者,更好的是,避免复制数据而只复制指针地址并防止本地数据被终止。
代码:
void getImage(unsigned char data[]){
// Get the image in 1d array format
fc::Image rawImage;
//Initializes Image object
error = camera.RetrieveBuffer( &rawImage );
//retrieve and return data
unsigned char *temp = rawImage.GetData(); //returns point to data
for(int i = 0; i < IMG_SIZE; i++){
data[i] = temp[i];
}
}
简单调用
unsigned char data[size];
getImage(data);
最佳答案
问题在于你的数据是栈上的本地对象。一旦您的函数返回,fc::Image
对象(及其指向的数据)将被销毁。我只看到三种从函数中获取数据的可能方法:
- 将数据复制到目标数组(就像你已经做的那样,但可能使用
memcpy
或类似的东西而不是裸循环) - 将您的数据成员声明为静态的(因此即使在函数返回后它仍然存在),然后只需通过
data = rawImage.GetData()
将目标指针的值设置为指向数据> - 可能是最好的一个,如果你能做到:改变你的 API!只需接受指向
fc::Image
对象的指针或引用,并将其作为参数传递给camera.RetrieveBuffer
,这样您的数据就会到达正确的开始位置。或者另一种方法是按值返回对象,在这种情况下不接受任何参数。
第二个有点古怪,因为数据只有在其他人不再调用该函数时才有效,老实说这是一种糟糕的做法,所以我不建议数字2.
另外,这个 API 本身就很糟糕。传入的指针有足够容量的保证是什么?而且,用户如何知道他们收到的数据有多长?您不会返回尺寸值或任何东西。
编辑:
有一种更合适的方法来处理第 2 项。您可以这样做:
#include <unordered_map>
// Ideally this would be wrapped in a class or something. Don't use globals.
std::unordered_map<unsigned char*, fc::Image> images;
void getImage(unsigned char data*){
// Get the image in 1d array format
fc::Image rawImage;
//Initializes Image object
error = camera.RetrieveBuffer( &rawImage );
data = rawImage.getData();
images.insert(std::make_pair(data, move(rawImage)));
}
这使用 unordered_map
来让您的本地对象保持事件状态,因此您可以安全地将指针返回到它们而不必担心对象的生命周期。
但在这种情况下,您还必须创建一个清理函数:
void destroyImage(unsigned char data*){
images.erase(data);
}
由于 map 将永远保留您的对象,如果您不断获取新图像,您很快就会开始填满内存。如果您使用此方法,那么您的用户将不得不在他们不再需要数据时立即调用 destroyImage()
以避免内存泄漏。这种做法违背了现代 C++ 中鼓励自动清理的内存管理指南,虽然这将取决于您的用户调用您的清理功能,这有点不安全,但在我看来这仍然是您可以做的最好的事情,因为您无法更改您的 API。
如果您可以扩展您的 API 以包含这样的功能,这绝对是延长本地对象生命周期的更好方法,而不是将它们标记为静态。
关于c++ - 不使用 For 循环将数据从指向局部数组的指针传输到全局数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37416307/