获取结构成员的指针后无法正确访问

cannot access properly after getting pointer of a member of struct

在下面的例子中,我基本上是尝试获取数据中vector的元素的指针。对我来说,这三种方法似乎做同样的事情,但结果不同 :

123
9.88131e-324
5.61658e+259

并且只有通过第一种方法,才能正确访问元素。你能指出我的错误并解释为什么这三种方法的输出不同吗?

#include<vector>
#include<iostream>
using namespace std;

struct Data
{
  vector<double> a;
  Data() : a(vector<double>(100, 123.0)) {};
  double* get_ptr(int idx){
    return &a[idx];
  }
  void get_ptr2(int idx, double* ptr){
    ptr = &a[idx];
  }
};

int main(){
  auto data = Data();
  std::cout << *(data.get_ptr(10)) << std::endl; 

  double value;
  data.get_ptr2(10, &value);
  std::cout << value << std::endl; 

  double* ptr;
  data.get_ptr2(10, ptr);
  std::cout << *ptr << std::endl; 
}

您在get_ptr2中遇到的主要问题,例如:

  void get_ptr2(int idx, double* ptr){
    ptr = &a[idx];
  }

ptr 将是 copy 来自 main() 的指针。当您在函数中更改 ptr 的值时,您正在更改 ptr 本地副本 的值,结果在 main().

(注意 下面向您展示了如何完成您正在尝试的事情,但不推荐它作为正确的方法。请参阅@tadman 在您下方的评论原题)

您可以从 main() 传递指针的 地址 并更新该地址的指针,例如

  void get_ptr2(int idx, double** ptr){
    *ptr = &a[idx];
  }

并称为:

  double* ptr;
  data.get_ptr2(10, &ptr);
  std::cout << *ptr << std::endl; 

指针将保存正确的地址,取消引用指针将提供所需的值。

您对 value 的选择有点不同。在那里,您可以传递指针引用,重载第二个 get_ptr2(),例如

  void get_ptr2(int idx, double*& ptr){
    ptr = &a[idx];
  }

但是,您不能传递 value 的地址,它是一个 rvalue 作为参考。您可以创建第二个指针保存地址并更新指针保存的值,例如

  double value, *valptr = &value;
  data.get_ptr2(10, valptr);
  std::cout << *valptr << std::endl; 

这也输出了所需的值。

示例代码

完整的例子是:

#include<vector>
#include<iostream>
using namespace std;

struct Data
{
  vector<double> a;
  Data() : a(vector<double>(100, 123.0)) {};
  double* get_ptr(int idx){
    return &a[idx];
  }
  void get_ptr2(int idx, double*& ptr){
    ptr = &a[idx];
  }
  void get_ptr2(int idx, double** ptr){
    *ptr = &a[idx];
  }
};

int main(){
  auto data = Data();
  std::cout << *(data.get_ptr(10)) << std::endl; 

  double value, *valptr = &value;
  data.get_ptr2(10, valptr);
  std::cout << *valptr << std::endl; 

  double* ptr;
  data.get_ptr2(10, &ptr);
  std::cout << *ptr << std::endl; 
}

例子Use/Output

$ ./bin/get_ptr
123
123
123