Хобрук: Ваш путь к мастерству в программировании

Создайте объект структуры в функции и передайте его указатель

Я пытаюсь передать пустой указатель структуры в функцию с именем «инициализировать» в качестве выходного параметра, а затем, после завершения функции, я могу получить объект, на который указывает указатель структуры. Происходит некоторое неожиданное поведение, и я не совсем понимаю.

Ниже мой код:

static void initialize(complex_struct*& infoPtr)
{
    complex_struct myInfo;
    infoPtr = &myInfo;
    // some other codes that modify the contents of myInfo
    infoPtr->input_components = 3;
}

static void myfunction()
{
    complex_struct* infoPtr = nullptr;
    initialize(infoPtr);
    std::cout << infoPtr->input_components << std::endl;
}

Результатом этого является произвольное большое целое число. Но я ожидал, что будет напечатано целое число 3.

Ограничения: я не могу изменять complex_struct; это структура Third_Party, которую необходимо использовать. Кроме того, причина, по которой мне нужно, чтобы initialize() была отдельной функцией, заключается в том, что я выполняю измерение производительности при выделении памяти для complex_struct. Поэтому перемещение первой строки кода в initialize() в myfunction() не является идеальным решением.

30.09.2015

  • Вы возвращаете (через ссылку на указатель) указатель на объект стека, который инициализируется, когда начинается initialize, и уничтожается, когда заканчивается initialize. Устаревший указатель — плохой указатель. 30.09.2015

Ответы:


1

Вы возвращаете указатель на объект в кадре стека. Этот объект удаляется, когда функция возвращается. У вас висячий указатель в myfunction.

Пути решения проблемы:

Выделить память из кучи

static void initialize(complex_struct*& infoPtr)
{
    infoPtr = new complex_struct ;
    infoPtr->input_components = 3;
}

Обязательно освободите память в вызывающей функции.

Используйте объект вместо указателя

static void initialize(complex_struct& info)
{
    info.input_components = 3;
}

и измените его использование:

static void myfunction()
{
    complex_struct info;
    initialize(info);
    std::cout << info.input_components << std::endl;
}
30.09.2015
  • Строка кода complex_struct myinfo; связаны с затратным по времени выделением памяти? Я пытаюсь сохранить действия по выделению памяти в функции initialize(), чтобы выполнить точное измерение производительности. 30.09.2015
  • Я предполагаю, что вы спрашиваете, включает ли это динамическое выделение памяти. Ответ на это: нет, не имеет. Этот объект создается с использованием стековой памяти. 30.09.2015

  • 2

    Вы пытаетесь использовать указатель на локальную переменную за пределами ее области действия. В вашем примере экземпляр myInfo внутри initialize() будет удален после выхода из функции, а адрес, который вы запомнили, будет указывать на случайную мусорную память. Вы никогда не должны использовать указатели на локальные переменные за пределами их области видимости.

    Как решить проблему? Проще всего было бы отказаться от указателя здесь и вместо этого передать вашу структуру по неконстантной ссылке. Код будет выглядеть следующим образом:

    void initialize(complex_struct& info)
    {
        // some other codes that modify the contents of myInfo
        info.input_components = 3;
    }
    
    void myfunction()
    {
        complex_struct info;
        initialize(info);
        std::cout << info.input_components << std::endl;
    }
    

    В предложенном коде есть один тонкий недостаток: фактически информация инициализируется дважды. Первый раз при создании экземпляра (complex_struct info) и второй раз внутри функции initialize(). В этом примере это не имело бы заметного эффекта (info выделено в стеке, и я не думаю, что у него есть какой-либо нетривиальный конструктор), но может быть более серьезной проблемой в других настройках. Лучшим способом инициализации в этом случае было бы вернуть структуру из функции инициализатора и полагаться на копирование-исключение для оптимизации всех копий. Код иллюстрации:

    complex_struct initialize()
    {
        complex_struct info;
        // some other codes that modify the contents of myInfo
        info.input_components = 3;
        return info;
    }
    
    void myfunction()
    {
        complex_struct info = initialize();
        std::cout << info.input_components << std::endl;
    }
    
    30.09.2015
    Новые материалы

    Освоение информационного поиска: создание интеллектуальных поисковых систем (глава 1)
    Глава 1. Поиск по ключевым словам: основы информационного поиска Справочная глава: «Оценка моделей поиска информации: подробное руководство по показателям производительности » Глава 1: «Поиск..

    Фишинг — Упаковано и зашифровано
    Будучи старшим ИТ-специалистом в небольшой фирме, я могу делать много разных вещей. Одна из этих вещей: специалист по кибербезопасности. Мне нравится это делать, потому что в настоящее время я..

    ВЫ РЕГРЕСС ЭТО?
    Чтобы понять, когда использовать регрессионный анализ, мы должны сначала понять, что именно он делает. Вот простой ответ, который появляется, когда вы используете Google: Регрессионный..

    Не зря же это называют интеллектом
    Стек — C#, Oracle Опыт — 4 года Работа — Разведывательный корпус Мне пора служить Может быть, я немного приукрашиваю себя, но там, где я живу, есть обязательная военная служба на 3..

    LeetCode Проблема 41. Первый пропущенный положительный результат
    LeetCode Проблема 41. Первый пропущенный положительный результат Учитывая несортированный массив целых чисел, найдите наименьшее пропущенное положительное целое число. Пример 1: Input:..

    Расистский и сексистский робот, обученный в Интернете
    Его ИИ основан на предвзятых данных, которые создают предрассудки. Он словно переходит из одного эпизода в другой из серии Черное зеркало , а вместо этого представляет собой хронику..

    Управление состоянием в микрофронтендах
    Стратегии бесперебойного сотрудничества Микро-фронтенды — это быстро растущая тенденция в сфере фронтенда, гарантирующая, что удовольствие не ограничивается исключительно бэкэнд-системами..