Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
IvanPryamoy_2
0 / 0 / 0
Регистрация: 21.01.2013
Сообщений: 23
#1

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

06.02.2013, 17:48. Просмотров 399. Ответов 8
Метки нет (Все метки)

Я в функции создаю указатель на строку и потом этот указатель передаю в объект (поле объекта):

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 он продолжает жить как и в предыдущем примере? Две записи эквивалентны или есть какие-то нюансы?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.02.2013, 17:48
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Тонкости кода: wchar_t* FilterFiles = L"cool"; (C++):

Error C2664: невозможно преобразовать из "wchar_t" в "const wchar_t *" - C++
Вот так работает: wchar_t buf; Edit_GetText(hE, buf, sizeof(buf)); if(buf) { wchar_t b; _itow_s(wcscspn(buf, &buf), b, 10); ...

В зависимости от времени года "весна", "лето", "осень", "зима" определить погоду "тепло", "жарко", "холодно", "очень холодно" - C++
В зависимости от времени года "весна", "лето", "осень", "зима" определить погоду "тепло", "жарко", "холодно", "очень холодно". Я так...

Невозможно преобразовать параметр 1 из "const wchar_t [12]" в "const char *" - C++
Писал программу. Дошел до наложения текстур. Пытаюсь наложить 4-й час. Много разных ошибок. Все ошибки гуглил. На данный момент ошибка...

Реализовать классы "Воин", "Пехотинец", "Винтовка", "Матрос", "Кортик" (наследование) - C++
Разработать программу с использованием наследования классов, реализующую классы: − воин; − пехотинец(винтовка); − матрос(кортик). ...

"Очистка" массива wchar_t - C++
Ребята скажите, есть массив wchar_t и есть функция получения длинны массива wcslen, как очистить массив так, что бы эта функция выдавала 0,...

Создать абстрактный класс "Издание" и производные классы "Книга", "Статья", "Электронный ресурс" - C++
1. Создать абстрактный класс Издание с методами, позволяющими вывести на экран информацию об издании, а также определить является ли данное...

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

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

Цитата Сообщение от IvanPryamoy_2 Посмотреть сообщение
Две записи эквивалентны или есть какие-то нюансы?
Две записи эквивалентны, но в первом коде будет передаваться указатель на то,откуда брать сторку, а во втором сама строка, которая "умрёт" после инициализации объекта MyObject(если я правильно понял).
1
Croessmah
Ушел
Эксперт CЭксперт С++
13557 / 7707 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
06.02.2013, 20:33 #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;
}
1
Изображения
 
Croessmah
Ушел
Эксперт CЭксперт С++
13557 / 7707 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
06.02.2013, 20:34 #4
Цитата Сообщение от IvanPryamoy_2 Посмотреть сообщение
в функции (где расположен этот код) создается временный объект- массив, хранящий строку L"cool",
создается только указатель. Строковые литералы же хранятся в другом месте. См. пример выше:
0
IvanPryamoy_2
0 / 0 / 0
Регистрация: 21.01.2013
Сообщений: 23
07.02.2013, 07:30  [ТС] #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 уничтожается после выхода из функции, поэтому указатель смотрит в свободную память с ПОКА корректным значением.
0
Croessmah
Ушел
Эксперт CЭксперт С++
13557 / 7707 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
07.02.2013, 08:29 #6
Если бы Вы внимательно посмотрели на результат, то увидели бы, что все четыре указателя указывают на одну и ту же память. Потому что строковые литералы создаются единожды. Посмотрите дизассемблированный код т увидите где располагаются строковые литералы.
1
IvanPryamoy_2
0 / 0 / 0
Регистрация: 21.01.2013
Сообщений: 23
07.02.2013, 08:39  [ТС] #7
Цитата Сообщение от Croessmah Посмотреть сообщение
Если бы Вы внимательно посмотрели на результат, то увидели бы, что все четыре указателя указывают на одну и ту же память. Потому что строковые литералы создаются единожды. Посмотрите дизассемблированный код т увидите где располагаются строковые литералы.
Думаю в вашем примере произошла оптимизация, поэтому была произведена подстановка кода функции вместо ее вызова (типа inline- подстановок), а также создана единая переменная со строковым литералом (вместо 4 переменных).

Иначе я просто не могу понять где хранятся переменные со строковыми литералами? В глобальной памяти? Что-то я об этом ничего не слышал раньше.
0
Croessmah
Ушел
Эксперт CЭксперт С++
13557 / 7707 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
07.02.2013, 08:58 #8

Не по теме:

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



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

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

{ссылка удалена}
0
07.02.2013, 09:12
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.02.2013, 09:12
Привет! Вот еще темы с ответами:

Создать класс "Книга" с полями "название книги", "количество страниц", "год издания" - C++
Создать класс Книга поля: название книги,количество страниц,год издания методы: вычислить сколько лет книге и количество дней прошедших...

Создать класс "Вентилятор" содержащий в себе классы: "Двигатель", "Контроллер", "Пульт управления" - C++
Помогите с кодом написания задачи, не понимаю как написать классы в классе. Нужно создать класс &quot;вентилятор&quot; содержащий в себе классы:...

Определить тип данных "Запись", имеющий поля "Фамилия", "Пол", "Зарплата" - C++
определить тип данных запись имеющий поля фамилия пол зарплата. определить массив из 10 записей. в программе ввести в массив данные и...

Структура «Преподаватель» с полями "ФИО", "стаж", "категория", "нагрузка" - C++
Функция - расчёт зарплаты по нагрузке и оплате часа для определенной категории. Категория Оплата часа Вторая 150 Первая 200 ...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.