Вектор указателя указывает на NULL при использовании push_back () - PullRequest
0 голосов
/ 17 июня 2019

В моем коде есть следующая структура, которая присваивает случайным образом сгенерированные x и y целочисленные значения:

struct A{
    int x,y;
    A () : x(random_gen_num),y(random_gen_num) {};   
};

У меня есть вектор объектов, и мне нужен вектор указателей, указывающих на каждый объект:

vector<A> a(5);
a.reserve(5);

vector<const A*> apoint(5);
apoint.reserve(5);
for(const A thisA : a){
    apoint.push_back(&thisA);
}

Когда я пытаюсь распечатать их, используя:

for(unsigned int i = 0; i<5; i++){
    cout<< i <<"\t"<< a[i].x <<"\t" << &a[i]<<"\t" << apoint[i] <<endl;
}

Я получаю все свои точки в виде пустых указателей следующим образом:

0       8       0x29b1bd0       0
1       8       0x29b1bd8       0
2       1       0x29b1be0       0
3       8       0x29b1be8       0
4       6       0x29b1bf0       0

Код кажется мне логичным и работает, когда я говорю apoint[i] = &a[i] в цикле for, но в реальном случае это недопустимо, так как индексы apoint и a могут не совпадать. Насколько мне известно Я не смог найти ответ на вопрос с похожей проблемой. Есть ли лучший способ вставить указатели в векторы?

Ответы [ 2 ]

1 голос
/ 17 июня 2019
vector<const A*> apoint(5);

Создает vector и предварительно загружает его с 5 const A* с, которые будут инициализированы по умолчанию. Это означает, что apoint, прежде чем push_back, что-либо содержит 5 нулевых указателей. Поскольку размер уже равен 5, apoint.reserve(5); фактически ничего не делает. Это также относится к vector<A> a(5);.

Это значит

for(unsigned int i = 0; i<5; i++){
    cout<< i <<"\t"<< a[i].x <<"\t" << &a[i]<<"\t" << apoint[i] <<endl;
}

распечатывает эти 5 нулевых указателей, прежде чем он достигнет пяти, добавленных с помощью push_back. Изменить

vector<const A*> apoint(5);

до

vector<const A*> apoint;

для создания пустого vector или присвоения этих 5 указателей с помощью apoint[index] = &thisA; и удаления The apoint.reserve (5); `.

Но ...

for(const A thisA : a){
    apoint.push_back(&thisA);
}

Нужно разбить немного больше, чтобы обнаружить вторую ошибку. const A thisA : a создает копии элементов в a, которые существуют только для одной итерации цикла for. Эти указатели слишком недолговечны, чтобы быть вам полезными. Требуются ссылки на значения в a, а не на копии, поэтому

for(const A thisA : a){
    apoint.push_back(&thisA);
}

должно быть

for(const A & thisA : a){
    apoint.push_back(&thisA);
}

Примечание о хранении ссылок на элементы в vector s: Обычно это плохая идея. Если задать новый вопрос и объяснить свою цель, мы сможем предложить лучшие альтернативы. Если вам действительно нужны указатели на vector элементов, будьте очень осторожны, чтобы не нарушить правил аннулирования итераторов .

1 голос
/ 17 июня 2019
for(const A thisA : a){
    apoint.push_back(&thisA);
}

Вы нажимаете указатель, который больше не действителен в следующем цикле. Вам нужна ссылка (A&).

Все это говорит, конечно, при условии, что вам действительно нужен вектор указателей (не так ли?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...