Может ли кто-нибудь объяснить, почему указатели перезаписываются при объявлении переменных внутри цикла?
Например, с учетом следующего фрагмента и пользовательского ввода 1 и 2. Я ожидаю, что массив pNums
содержит 2 указателя на 2 целых числа, содержащих значения 1 и 2 соответственно.
Но вместо этого консоль печатает 2
и 2
;
#include <iostream>
using namespace std;
//Input "1 2"
int main() {
int* pNums[2];
for(int i = 0; i < 2; i++){
int num;
cin >> num;
pNums[i] = (&num);
}
cout << (*pNums[0]) << endl;
cout << (*pNums[1]) << endl;
}
Почему это так? И как мне обойти это? Что если, например, мы не знаем, сколько чисел введет пользователь, и вместо цикла for
мы получим цикл while
? Пока не будут выполнены некоторые условия, мы хотим продолжать создавать новые указатели и сохранять их в векторе pNums
?
3 ответа
Существует только один num
, и вы перезаписываете это. (и затем вызываете неопределенное поведение, но не обращайте на это внимания.)
Есть два простых способа избежать этой ошибки.
1) Храните объекты, а не указатели:
int nums[2];
for(int i = 0; i < 2; i++){
cin >> nums[i];
}
2) Используйте динамическое размещение:
int* pNums[2];
for(int i = 0; i < 2; i++){
int *p=new int;
cin >> *p;
pNums[i] = p;
}
for(int i = 0; i < 2; i++){
int num; //< this is num. It lives here.
cin >> num;
pNums[i] = (&num); //< you have taken the address of num (twice!)
}
// here is when 'num' is destroyed (no longer in scope)
// so this is now pointing at something that doesn't exist.
cout << (*pNums[0]) << endl;
Указатели, которые вы храните в pNums
, относятся к двум экземплярам переменной num
в блоке for
. В каждой итерации цикла for
существует один экземпляр переменной, и эти переменные живут только до тех пор, пока не будет достигнут конец их соответствующей итерации тела цикла for
.
Следовательно, ваши указатели будут недействительными, когда завершается цикл for
, и поэтому он пытается разыменовать их, например, с помощью. *pNums[0]
вызывает неопределенное поведение .
Не хранить указатель, хранить значения:
#include <iostream>
using namespace std;
//Input "1 2"
int main() {
int pNums[2];
for(int i = 0; i < 2; i++){
int num;
cin >> num;
pNums[i] = num;
}
cout << pNums[0] << endl;
cout << pNums[1] << endl;
}
И если вам нужно переменное количество записей в массиве, используйте std::vector
.
Похожие вопросы
Связанные вопросы
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который должен быть) скомпилирован с помощью компилятора C ++. Используйте тег для конкретной версии для вопросов, связанных с конкретной версией стандарта [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] или [C ++ 23] и т. Д. .