向量,倾斜数据,将其作为指针传递给函数时

vector, skewed data, when passing it to a function as pointer

我有一个采用整数指针的接口(我无法更改此接口)。我想在其他一些 class 中填充 vector,并希望通过我的 class 从客户端代码调用该接口。但是当我从 vector 中检索值时,它总是从 0 开始。我不想将 vector 声明为 static 并且我不能通过 -值或引用。我只能传递整数指针。

我已经编写了模拟此场景的代码。

#include <iostream>
#include <vector>

//--Class SpMx; I can't change anything here--//
class SpMx{
public:
  void getVector(int* values_);
  void showValues();
private:
  int* values;
};

//--definition--//
void SpMx::getVector(int* values_) {
  values = values_;
}


void SpMx::showValues(){

  for(size_t i = 0; i< 13; ++i)

    std::cout<<values[i]<<std::endl;
}

//--class Mx; I can make change here--//
class Mx{

public:
  Mx() = default;
  SpMx* myFunc();
};

//--definition--//
SpMx* Mx::myFunc(){

  //hard coded for testing
  int ary[] = {2, 110, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160};
  std::vector<int> myVector(ary, ary +sizeof(ary)/sizeof(int)); 
  SpMx* sMx_obj = new SpMx();
  sMx_obj->getVector(&myVector[0]);
  return sMx_obj;
}

//--main--//
int main(){
  Mx mx_obj;
  SpMx* spmx_obj;
  spmx_obj = mx_obj.myFunc();
  spmx_obj->showValues();
  delete spmx_obj;
  return 0;
}

//output 
0, 110, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160

这个函数会给你带来麻烦

SpMx* Mx::myFunc(){    
  int ary[] = {2, 110, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160};
  std::vector<int> myVector(ary, ary +sizeof(ary)/sizeof(int)); 
  SpMx* sMx_obj = new SpMx();
  sMx_obj->getVector(&myVector[0]);
  return sMx_obj;
}

向量myVector在此函数的范围内声明。然后,您的 sMx_objvalues 指针指向此向量内存。一旦 vector 超出范围,该内存现在就是垃圾。但是你 return SpMx 对象,指针仍然指向那个垃圾。

您需要确保您的 SpMx 对象拥有该内存,或者至少它所指向的数组与您的 SpMx 对象一样存在。

您的 SpMx 初始值设定项:

void SpMx::getVector(int* values_) {
  values = values_;
}

显然需要一个指向数组开头的指针,SpMx 将被允许保留该数组(或者至少其生命周期与 SpMx 一样长)。所以声明在堆上(并且不要使用std::vector的内部实现,那是不给外人使用的):

#include <algorithm>

SpMx* Mx::myFunc(){

  //hard coded for testing
  int ary[] = {2, 110, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160};
  int *p = new int[14];
  std::copy(ary, ary+13, p);

  SpMx* sMx_obj = new SpMx();

  sMx_obj->getVector(p);
  return sMx_obj;
}

不要忘记在 SpMx 处理完数组后删除它(例如在 SpMx 析构函数中),否则会发生内存泄漏。