不使用For循环将数据从指针传输到本地数组到全局数组

时间:2016-05-24 14:18:17

标签: c++ arrays pointers

  • 我有一个从相机中检索图像的功能。
  • 此函数有一个名为GetData()的函数,它返回一个指向摄像机创建的Image对象所包含数据的指针。
  • 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);

1 个答案:

答案 0 :(得分:1)

问题在于您的数据是堆栈中的本地对象。函数返回后,fc::Image对象(及其指向的数据)将被销毁。我只看到三种可能的方法从函数中获取数据:

  • 将数据复制到目标数组(就像您已经做过的那样,但可能使用memcpy或其他内容而不是裸体for循环)
  • 声明您的数据成员是静态的(因此即使在函数返回后它仍然存在),然后只需将目标指针的值设置为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);
}

由于地图会永久保留您的物体,因此如果您不断获取新图像,您很快就会开始填充内存。如果您使用此方法,那么您的用户必须在不再需要数据时立即致电destroyImage(),以避免基本上泄露内存。这种现代C ++中的内存管理指南再次鼓励自动清理,而这取决于你的用户调用你的清理功能,这有点不安全,但它仍然是你认为最好的,因为你无法更改您的API。

如果您可以扩展您的API以包含此类函数,这绝对是延长本地对象生命周期的更好方法,而不是将它们标记为静态。