Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
82 / 2 / 0
Регистрация: 10.02.2024
Сообщений: 165

Функция возвращает string и механизм перемещения

25.01.2025, 04:03. Показов 1574. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем доброго дня!

C++
1
2
3
4
5
6
string foo() {
    string res = "line";
    return res;
}
 
string str = foo();
Как я понял, современные компиляторы не будут копировать res в str, они оставят строку "line" в памяти на своем месте, но удалят переменную res. А вот переменной str присвоят указатель на строку "line".

Таким образом, не тратим времени на долго копирование, но получаем тот же результат.

Вот только у меня вопрос, на который не могу найти пояснение:
У меня в голове есть 2 парадигмы. 1 - Локальные переменные, это автоматическое "занятие" памяти и его освобождение, после выхода из области видимости. 2 - Чтобы "занятая" память оставалась таковой за пределами области видимости, мы ее должны "полноценно" "занять". А после она будет занята, до тех пор, пока мы ее сами не освободим.

Так вот, при современном копировании память остается занятой за пределами области видимости создания, но, что произойдет, когда я выйду из области видимости str? Память для строки "line" сама освободиться? Или без принудительного освобождения память "утечет"?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
25.01.2025, 04:03
Ответы с готовыми решениями:

функция choose(n:byte; c1: string): string возвращает значение из списка
функция choose(n:byte; c1: string): string возвращает значение из списка, выбранное на основании значения аргумена N. если N=1 то...

Функция, которая возвращает string
Всем привет. Есть пример самого элементарного многофайлового проекта, но он не хочет компилироваться. Ошибка: Error C4430 missing...

dllexport Функция которая возвращает string
У меня есть большая функция в Visual C++ которая читает GUID раздела диска Она возвращается из функции как std::wstring #define...

6
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
25.01.2025, 07:40
Лучший ответ Сообщение было отмечено Elesh_Makfa как решение

Решение

Цитата Сообщение от Elesh_Makfa Посмотреть сообщение
string foo()
Что такое string? Это std::string? Как мы об этом должны догадаться?

Цитата Сообщение от Elesh_Makfa Посмотреть сообщение
Как я понял, современные компиляторы не будут копировать res в str, они оставят строку "line" в памяти на своем месте, но удалят переменную res. А вот переменной str присвоят указатель на строку "line".
Да и нет.

Переменная res действительно исчезнет, если компилятор применит RVO. То есть результат будет формироваться сразу в переменной str.

Однако никакого "присвоят указатель на строку "line" не будет. Класс std::string копирует данные внутрь себя. Он хранит свою копию строки, а не указатель на внешние данные. Он не умеет никакого "присвоят указатель на строку". Строка "line" будет сохранена внутри str в каком-то виде (скопирована внутрь). После этого к исходному литералу "line" объект str уже не имеет никакого отношения.

И ни о каком "присвоят" вообще тут речи не идет. В вашем коде нет ни одного присваивания.

Цитата Сообщение от Elesh_Makfa Посмотреть сообщение
Таким образом, не тратим времени на долго копирование, но получаем тот же результат.
Не тратим время на копирование из res в str, потому что res просто не будет вообще, а вместо res результат будет сформирован прямо в str. Однако от копирования литерала "line" внутрь str мы никак не избавились. Это копирование никуда не денется.

Цитата Сообщение от Elesh_Makfa Посмотреть сообщение
Так вот, при современном копировании память остается занятой за пределами области видимости создания, но, что произойдет, когда я выйду из области видимости str?
Объект str будет уничтожен. Его деструктор отвободит всю память, которая принадлежит str.

Цитата Сообщение от Elesh_Makfa Посмотреть сообщение
Память для строки "line" сама освободиться?
... только к литералу "line" все это не имеет никакого отношения. Литерал "line" никак не связан с str. Литерал "line" живет в статической памяти и не освобождается никогда.

Цитата Сообщение от Elesh_Makfa Посмотреть сообщение
Функция возвращает string и мханизм перемещения
Пока что во всем этом описании нигде и никак не был замешан "механизм перемещения". Поэтому не совсем понятно, почему вы упоминаете его в заголовке.
1
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
25.01.2025, 12:28
Лучший ответ Сообщение было отмечено Elesh_Makfa как решение

Решение

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Что такое string? Это std::string? Как мы об этом должны догадаться?
Что это меняет относительно сути заданного вопроса?

Добавлено через 12 минут
Я расскажу как понимаю про RVO, а если где навру - надеюсь меня поправят знающие товарищи.

Исходный код будет примерно преобразован компилятором в такое:

C++
1
2
3
4
5
6
void foo(string& res) {
    res = "line";
}
 
string str; 
foo(str);
Но и это не совсем правда, т.к. в приведенном мною коде будет:
1) вызов конструктора str без параметров;
2) вызов оператора = для res (оно же str)
ну и все на этом. (вызов деструктора str будет, конечно, но это и так понятно)

А не совсем правда потому, что по факту будет вызван только конструктор для string(const char*) и все, лишнего конструирования и присваивания не будет.
Т.к. компилятор на самом деле передаёт не ссылку на уже сконструированный объект str, а как бы адрес выделенной на стеке памяти, в которой будет размещен и сразу сконструирован с нужными параметрами объект res (оно же str) в тот момент, когда внутри функции первый раз появится определение res
1
фрилансер
 Аватар для Алексей1153
6431 / 5626 / 1126
Регистрация: 11.10.2019
Сообщений: 14,967
25.01.2025, 14:14
Цитата Сообщение от KSergey9 Посмотреть сообщение
1) вызов конструктора str без параметров;
- а точнее, конструктор по умолчанию
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12919 / 6787 / 1817
Регистрация: 18.10.2014
Сообщений: 17,169
25.01.2025, 17:15
Цитата Сообщение от KSergey9 Посмотреть сообщение
Что это меняет относительно сути заданного вопроса?
Абсолютно все. Это самое главное в данном вопросе. Мой ответ построен на "разумном предположении", что это std::string. Без возможности сделать такое предположение вопрос будет являться бессмысленным "словесным салатом", ни о каких ответах на который речи идти не будет.

Цитата Сообщение от KSergey9 Посмотреть сообщение
Я расскажу как понимаю про RVO, а если где навру - надеюсь меня поправят знающие товарищи. Исходный код будет примерно преобразован компилятором в такое:

C++
1
2
3
void foo(string& res) {
    res = "line";
}
Неверно, так как теперь здесь используется оператор присваивания. Ни о каком использовании оператора присваивания, разумеется, речи быть не может.

Цитата Сообщение от KSergey9 Посмотреть сообщение
А не совсем правда потому, что по факту будет вызван только конструктор для string(const char*) и все, лишнего конструирования и присваивания не будет.
Именно. К чему тогда все это? Разумеется, еще с той оговоркой, что говорить об этом бесполезно, пока не известно, что такое string. В частности, откуда вы взяли, что конструктор для string(const char*) вообще существует? По каковой причине первый и главный вопрос, который сразу же задает любой мало-мальски разбирающийся в теме человек: что такое string?

Цитата Сообщение от KSergey9 Посмотреть сообщение
Т.к. компилятор на самом деле передаёт не ссылку на уже сконструированный объект str, а как бы адрес выделенной на стеке памяти, в которой будет размещен и сразу сконструирован с нужными параметрами объект res (оно же str) в тот момент, когда внутри функции первый раз появится определение res
Все это прекрасно, но вопрос ТС на 99% не об этом вообще. Вопрос о некоем "механизме перемещения" и о том, как во всем этом будет участвовать литерал-инициализатор. Для ответа на эти вопросы нужно знать не только объявления конструкторов, но полную семантику этих конструкторов. По каковой причине первый и главный вопрос, который сразу же задает любой мало-мальски разбирающийся в теме человек: что такое string?
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
25.01.2025, 17:41
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Неверно, так как
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Именно [подразумевается "именно так"].
Вот бы вы определились с учетом того, что все нужные оговорки я вовремя делал.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
К чему тогда все это?
Чтобы методологически понятно и внятно всё это разъяснить.
Ибо ваше разъяснение лично я бы не понял, если бы не знал о чем речь.

Вы же не закрепляете за собой право на возможность эксклюзивно отвечать?

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
В частности, откуда вы взяли, что конструктор для string(const char*) вообще существует?
Бестолковые придирки и умничание пошло ради умничания.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
который сразу же задает любой мало-мальски разбирающийся в теме человек: что такое string?
Ну вот вы задали - полегчало? ну и славно.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вопрос о некоем "механизме перемещения
Мне очевидно, что ТС сделал неправильное предположение относительно того как работает RVO.
Вам нет? ну ок.
0
87 / 87 / 18
Регистрация: 11.06.2018
Сообщений: 302
25.01.2025, 20:56
Цитата Сообщение от KSergey9 Посмотреть сообщение
Бестолковые придирки и умничание пошло ради умничания.
Дык нет же. Это было пояснение зачем знать что такое string. А вдруг это не std::string, а какой-то другой string, тогда и предполагать, что у него есть такой конструктор тоже нельзя наверняка.

Цитата Сообщение от KSergey9 Посмотреть сообщение
Ну вот вы задали
Я бы тоже такой вопрос задал. Абсолютно нормальный вопрос для возможности дать верный ответ.

Цитата Сообщение от KSergey9 Посмотреть сообщение
Мне очевидно, что ТС сделал неправильное предположение относительно того как работает RVO.
Дык нет же. ТС сделал неправильное предположение относительно того как str будет обращаться с литералом "line" и ТС не знал или не соотнёс что "line" имеет статический класс хранения. А про то как работает RVO он всё правильно понял (за исключением того, что там инициализация вместо присваивания, замечание о чём уже сделал TheCalligrapher):
Цитата Сообщение от Elesh_Makfa Посмотреть сообщение
переменной str присвоят указатель на строку "line".
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.01.2025, 20:56
Помогаю со студенческими работами здесь

Функция stuff(c1,c2:string;n1,n2:byte) возвращает строку, полученную путём удаления позиций
функция-stuff(c1,c2:string;n1,n2:byte):string-возвращает строку символов,которая получена из строки c1 путём удаления позиций с n1...

Создать класс, в котором механизм перемещения кнопки, для создания его экземпляров
Доброго времени суток, форумчане! Помогите, пожалуйста, новичку ... Имеется два метода с механизмом перемещения кнопки: ...

Функция, которая принимает аргумент типа String и возвращает результат типа Double
Написать функцию, которая принимает аргумент типа String, и возвращает результат типа Double, который содержит числовой эквивалент значения...

Есть ли механизм быстрой инициализации структур содержащих vector, string ?
С быстрой инициализацией "простых структур" - содержащих типы данных известного размера , например, нулями - не проблема. memset (...

функция padright(c:string; ch:char; n:byte): string - выравнивает строку С по размеру N.
помогите! как записать эту функцию на языке Паскаль??? функция padright(c:string; ch:char; n:byte): string - выравнивает строку С по...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
PowerShell Snippets
iNNOKENTIY21 11.11.2025
Модуль PowerShell 5. 1+ : Snippets. psm1 У меня модуль расположен в пользовательской папке модулей, по умолчанию: \Documents\WindowsPowerShell\Modules\Snippets\ А в самом низу файла-профиля. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru