微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决获取结构体成员的指针后无法正确访问

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

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 将是来自 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);
  std::cout << *valptr << std::endl; 

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

示例使用/输出

$ ./bin/get_ptr
123
123
123

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。