#c #for-loop #vector
#c #для цикла #вектор
Вопрос:
Я пытаюсь воспроизвести проблему, чтобы задать ее в SO! но образец, который я хочу создать, сам по себе имеет проблему!
Как вы видите ниже, я написал простую программу, которая получает 5 элементов от пользователя и помещает их в u_char
вектор. После этого я пытаюсь распечатать элементы вектора.
#include <iostream>
#include <vector>
#include <stdint.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/ether.h>
int main(){
std::vector<u_char*> packets;
u_char packet[10];
std::cout << "Receiving Values :n";
for(int i=0; i<5; i ){
std::cin >> packet;
packets.push_back(packet);
}
std::cout << "nnnPrinting Values :n";
for(auto p : packets){
std::cout << p << "n";
std::cout << "------------n";
}
return 0;
}
И это результат:
me@me-MS-7693:~/Desktop/test$ ./a.out
Receiving Values :
aaaa
b
ccccc
ddd
ggggggg
Printing Values :
ggggggg
------------
ggggggg
------------
ggggggg
------------
ggggggg
------------
ggggggg
------------
Почему на выходе я получаю только последний элемент?
Ответ №1:
Это происходит потому, что вы помещаете указатель на один и тот же массив в набор vector
указателей. Это имеет два последствия:
- Все записи одинаковы и равны последней записи, потому что указатель всегда один и тот же; данные не копируются в вектор, только указатель, а указатель всегда один и тот же, потому что существует только один массив
packet[10]
. - Элемент вектора становится недействительным, как только локальная переменная, представляющая массив, выходит за пределы области видимости. Это не проблема для вашей примерной программы, потому что у вас есть только одна функция, но в программе, которая выполняет чтение в отдельной функции, это может привести к неопределенному поведению.
Чтобы устранить эту проблему, вам нужно изменить тип элементов вектора на что-то, что имеет функцию копирования, например std::string
.
Ответ №2:
потому что вы определили вектор или u_char * и снова и снова вводите одну и ту же ссылку, что означает, что вы получаете последнее значение во всех векторных ячейках.
Ответ №3:
Когда packets.push_back(packet);
указатель копируется как элемент vector
, а не как указатель. Это означает, что все они указывают на один и тот же адрес. Вот почему вы получаете тот же результат, когда распечатываете их в виде строки в стиле C.
Использование std::string
like std::vector<std::string>
приведет к ожидаемому результату.