В следующем примере я в основном пытался получить указатель элемента вектора в данных. Для меня эти три метода делают одно и то же, но результат разный:
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;
}
@ChrisMM Я хочу сохранить адрес переменной в указателе.
Зачем возвращать указатель, если вместо этого можно вернуть ссылку?
data.get_ptr2(10, &value);
никогда не сработает, но замена void get_ptr2(int idx, double** ptr){
на *ptr = &a[idx];
и использование data.get_ptr2(10, &ptr);
будет
Это должно быть operator[]
, а не что-то под названием get_ptr
.
@DavidC.Rankin Не могли бы вы объяснить, почему? Наивно размышляя, ptr
в get_ptr2
относится к типу double*
. Таким образом, я наивно думал, что установка адреса &a[idx]
на ptr
сработала.
Отвечает ли это на ваш вопрос? указатель не обновляет значение, на которое он указывает внутри функции void
Основная проблема, с которой вы столкнулись в 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
, который является значением r, в качестве ссылки. Вы можете создать второй указатель, содержащий адрес, и обновить значение, удерживаемое указателем, например.
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;
}
Пример использования/вывода
$ ./bin/get_ptr
123
123
123
ptr = &a[idx];
inget_ptr2
на самом деле ничего не делает. Я не уверен, пытаетесь ли вы сохранить адрес переменной вptr
или пытаетесь сохранить ее значениеptr
, поэтому больше ничем помочь не могу.