Форум программистов, компьютерный форум CyberForum.ru

Тонкости кода: wchar_t* FilterFiles = L"cool"; - C++

Восстановить пароль Регистрация
 
IvanPryamoy_2
0 / 0 / 0
Регистрация: 21.01.2013
Сообщений: 23
06.02.2013, 17:48     Тонкости кода: wchar_t* FilterFiles = L"cool"; #1
Я в функции создаю указатель на строку и потом этот указатель передаю в объект (поле объекта):

C++
1
2
wchar_t*  FilterFiles = L"cool";
TypeMyObject MyObject(FilterFiles);
Насколько я понимаю в функции (где расположен этот код) создается временный объект- массив, хранящий строку L"cool", а также указатель на этот объект FilterFiles. В объекте MyObject будет использоваться валидный указатель, поскольку временный объект пока существует в памяти (в стеке функции). По завершении работы функции указатель FilterFiles и объект "MyObject" теряют смысл, поскольку временный объект уничтожается и возможно память по адресу указателя скоро перезапишется. Поэтому использовать их в последующем будет ошибкой (например, в качестве возвращаемого значения или если они переданы в качестве параметров функции).

Мои размышления верны?

Добавлено через 16 минут
А какие отличия от этого кода:

C++
1
TypeMyObject MyObject(L"cool");
Тут тоже создается временный объект- массив, хранящий строку L"cool". Но сколько он "живет": после инициализации объекта MyObject он продолжает жить как и в предыдущем примере? Две записи эквивалентны или есть какие-то нюансы?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ласковая Киса
 Аватар для Ласковая Киса
82 / 8 / 1
Регистрация: 11.01.2013
Сообщений: 55
06.02.2013, 18:09     Тонкости кода: wchar_t* FilterFiles = L"cool"; #2
Цитата Сообщение от IvanPryamoy_2 Посмотреть сообщение
Насколько я понимаю в функции (где расположен этот код) создается временный объект- массив, хранящий строку L"cool", а также указатель на этот объект FilterFiles. В объекте MyObject будет использоваться валидный указатель, поскольку временный объект пока существует в памяти (в стеке функции). По завершении работы функции указатель FilterFiles и объект "MyObject" теряют смысл, поскольку временный объект уничтожается и возможно память по адресу указателя скоро перезапишется. Поэтому использовать их в последующем будет ошибкой (например, в качестве возвращаемого значения или если они переданы в качестве параметров функции).
Мои размышления верны?
Похоже на правду.

Цитата Сообщение от IvanPryamoy_2 Посмотреть сообщение
Тут тоже создается временный объект- массив, хранящий строку L"cool". Но сколько он "живет": после инициализации объекта MyObject он продолжает жить как и в предыдущем примере?
Нет.

Цитата Сообщение от IvanPryamoy_2 Посмотреть сообщение
Две записи эквивалентны или есть какие-то нюансы?
Две записи эквивалентны, но в первом коде будет передаваться указатель на то,откуда брать сторку, а во втором сама строка, которая "умрёт" после инициализации объекта MyObject(если я правильно понял).
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11822 / 6801 / 769
Регистрация: 27.09.2012
Сообщений: 16,868
Записей в блоге: 2
Завершенные тесты: 1
06.02.2013, 20:33     Тонкости кода: wchar_t* FilterFiles = L"cool"; #3
Цитата Сообщение от Ласковая Киса Посмотреть сообщение
которая "умрёт" после инициализации объекта MyObject(если я правильно понял).
Умрет указатель, а сам строковый литерал так и останется.
Как пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
 
char * getp(){
    char * p1=const_cast<char*>("LOL");
    return p1;
}
 
 
int main(){
    char * p1=const_cast<char*>("LOL");
    char * p2=const_cast<char*>("LOL");
    char * p3=const_cast<char*>("LOL");
    std::cout<<(void*)p1<<std::endl;
    std::cout<<(void*)p2<<std::endl;
    std::cout<<(void*)p3<<std::endl;
    std::cout<<(void*)getp()<<std::endl;
}
Изображения
 
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11822 / 6801 / 769
Регистрация: 27.09.2012
Сообщений: 16,868
Записей в блоге: 2
Завершенные тесты: 1
06.02.2013, 20:34     Тонкости кода: wchar_t* FilterFiles = L"cool"; #4
Цитата Сообщение от IvanPryamoy_2 Посмотреть сообщение
в функции (где расположен этот код) создается временный объект- массив, хранящий строку L"cool",
создается только указатель. Строковые литералы же хранятся в другом месте. См. пример выше:
IvanPryamoy_2
0 / 0 / 0
Регистрация: 21.01.2013
Сообщений: 23
07.02.2013, 07:30  [ТС]     Тонкости кода: wchar_t* FilterFiles = L"cool"; #5
Цитата Сообщение от Croessmah Посмотреть сообщение
Умрет указатель, а сам строковый литерал так и останется.
Как пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
 
char * getp(){
    char * p1=const_cast<char*>("LOL");
    return p1;
}
 
 
int main(){
    char * p1=const_cast<char*>("LOL");
    char * p2=const_cast<char*>("LOL");
    char * p3=const_cast<char*>("LOL");
    std::cout<<(void*)p1<<std::endl;
    std::cout<<(void*)p2<<std::endl;
    std::cout<<(void*)p3<<std::endl;
    std::cout<<(void*)getp()<<std::endl;
}
Пример ничего не показывает: память выделенная в функции getp() под строковый литерал ПОКА не перезаписалась, но приложение уже считает ее свободной. Если дальше будет запись в память (например, вызов функций или динамическая работа с памятью), то вполне возможно приложение запишет новые данные пересекая кусок памяти, где ранее хранился строковый литерал. А указатель честно продолжает смотреть на кусок памяти со строковым литералом, и после записи новых данных будет содержать мусор.

Другими словами кусок кода:
C++
1
wchar_t*  FilterFiles = L"cool";
эквивалентен куску с переменной функции:
C++
1
2
wchar_t PeremFunction[] = L"cool";
wchar_t*  FilterFiles = PeremFunction;
ну а переменная функции PeremFunction уничтожается после выхода из функции, поэтому указатель смотрит в свободную память с ПОКА корректным значением.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11822 / 6801 / 769
Регистрация: 27.09.2012
Сообщений: 16,868
Записей в блоге: 2
Завершенные тесты: 1
07.02.2013, 08:29     Тонкости кода: wchar_t* FilterFiles = L"cool"; #6
Если бы Вы внимательно посмотрели на результат, то увидели бы, что все четыре указателя указывают на одну и ту же память. Потому что строковые литералы создаются единожды. Посмотрите дизассемблированный код т увидите где располагаются строковые литералы.
IvanPryamoy_2
0 / 0 / 0
Регистрация: 21.01.2013
Сообщений: 23
07.02.2013, 08:39  [ТС]     Тонкости кода: wchar_t* FilterFiles = L"cool"; #7
Цитата Сообщение от Croessmah Посмотреть сообщение
Если бы Вы внимательно посмотрели на результат, то увидели бы, что все четыре указателя указывают на одну и ту же память. Потому что строковые литералы создаются единожды. Посмотрите дизассемблированный код т увидите где располагаются строковые литералы.
Думаю в вашем примере произошла оптимизация, поэтому была произведена подстановка кода функции вместо ее вызова (типа inline- подстановок), а также создана единая переменная со строковым литералом (вместо 4 переменных).

Иначе я просто не могу понять где хранятся переменные со строковыми литералами? В глобальной памяти? Что-то я об этом ничего не слышал раньше.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11822 / 6801 / 769
Регистрация: 27.09.2012
Сообщений: 16,868
Записей в блоге: 2
Завершенные тесты: 1
07.02.2013, 08:58     Тонкости кода: wchar_t* FilterFiles = L"cool"; #8

Не по теме:

Читайте книжки
ответ придет сам собой



Добавлено через 1 минуту
Сегменты данных и кода же есть
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.02.2013, 09:12     Тонкости кода: wchar_t* FilterFiles = L"cool";
Еще ссылки по теме:

Исправление кода игры "Змейка" C++
C++ Декларирование C++ кода в extern "C"
C++ "Очистка" массива wchar_t

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

Или воспользуйтесь поиском по форуму:
IvanPryamoy_2
0 / 0 / 0
Регистрация: 21.01.2013
Сообщений: 23
07.02.2013, 09:12  [ТС]     Тонкости кода: wchar_t* FilterFiles = L"cool"; #9
Цитата Сообщение от Croessmah Посмотреть сообщение
Добавлено через 1 минуту
Сегменты данных и кода же есть
А можно не так загадочно, а конкретно? Вы считаете, что строковые литералы хранятся в сегменте кода (который сохраняет свое значение на протяжении выполнения программы)?

Добавлено через 10 минут
Вот, нашел ответ:
"Т.е. строковые константы не создаются в момент их использования, а создаются еще при компиляции где-нибудь в сегменте данных. При этом если строковая константа используется дважды, то в зависимости от оптимизации/настройки компилятора в сегменте данных может быть создана еще одна такая же строка или использоваться указатель на одну и ту же сторку."

{ссылка удалена}
Yandex
Объявления
07.02.2013, 09:12     Тонкости кода: wchar_t* FilterFiles = L"cool";
Ответ Создать тему
Опции темы

Текущее время: 23:10. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru