#c #structure #allocation
#c #структура #распределение
Вопрос:
Учитывая, что у меня есть эта функция, которая заполняет элемент nicInfo
структуры:
nicList()
{
std::string num;
std::string nic_name_command;
nicInfo* nic = {};
nic = new nicInfo[nic_numbers];
for (int i = 0; i < nic_numbers; i )
{
nic_name_command = "ls /sys/class/net | sed -n -s " std::to_string(i 1) "p";
nic[i].name = sshObj->exec_ssh_command(nic_name_command);
}
return nic;
}
и это nicInfo
:
struct nicInfo
{
const char* name = {};
const char* ipAddr;
};
например, если у меня есть 3 сетевых адаптера (nic_numbers = 3), после отладки nic[4].имя не равно нулю или 0. он имеет это содержимое: name 0x1 <error: Cannot access memory at address 0x1> const char *
.
Я хочу печатать имена в цикле while следующим образом :
int i = 0 ;
while ((nic i)->name )
{
printf("nic name : %sn", (nic i)->name);
i ;
но он выходит из строя при i = 4, потому что его содержимое не равно нулю. что мне делать?
(моя функция и структура находятся на c , но цикл while для тестирования находится на c)
Комментарии:
1. Почему вы не используете
std::string
вnicInfo
структуре? Если указатель, возвращаемыйsshObj->exec_ssh_command(nic_name_command)
, становится недействительным, это также сделает этот указатель недействительным внутри структуры (назначение указателя копирует только указатель , а не память, на которую он может указывать).2. И если у вас есть три элемента в вашем
nic
массиве, почему вы пытаетесь использоватьnic[4]
то, что тогда было бы за пределами (как пятый элемент)?3. потому что я хочу использовать этот вывод (nicInfo.name ) в программе на c. @Someprogrammerdude
4. Я сказал, что хочу использовать цикл для печати всех членов nic.name Я не хочу печатать 5-й параметр, я хочу иметь триггер. если есть какой-либо лучший способ распечатать все элементы, я буду признателен, если вы мне скажете (в этом случае я не могу использовать число, подобное 4, для определения максимального значения цикла). @Someprogrammerdude
5. Вместо выделения массива ваших структур вы могли бы вместо этого использовать стандартные контейнеры, например
std::vector<struct nicInfo> myNics;
Контейнер знает, сколько объектов он содержит, и может легко (автоматически) изменять размер, если вам нужно добавить / удалить объекты.
Ответ №1:
Цикл
while ((nic i)->name )
{
printf("nic name : %sn", (nic i)->name);
i ;
выйдет за пределы памяти, для которой вы выделили nic
. Это приводит к неопределенному поведению.
Вам нужно использовать for
цикл только для перебора элементов, которые у вас действительно есть:
for (size_t i = 0; i < nic_numbers; i)
{
// ...
}
Это, конечно, требует, чтобы при nic_numbers
использовании в цикле совпадали совпадения, nic_numbers
используемые при выделении памяти. Если у вас нет размера, то вы не можете использовать условие, подобное вашему, для нахождения конца. Вам нужен фактический размер массива.
Я предлагаю запрограммировать все на C , так как тогда вы могли бы использовать вместо этого std::string
и std::vector<nicInfo>
, и это значительно упростило бы дело.
Примечание: для любого указателя p
и индекса i
выражение *(p i)
точно равно p[i]
. Для вашего случая это означает, что (nic i)->name
в точности равно nic[i].name
. Последнее обычно легче читать и меньше записывать.