в структуре

#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 . Последнее обычно легче читать и меньше записывать.