Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Выделение памяти, не вкурю 
:(
    Опции темы
Anikmar
Дата 9.2.2007, 01:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(nickless @  9.2.2007,  01:33 Найти цитируемый пост)
Но, каждый компилятор реализует и оптимирует их по-разному

Лично я на практике не встречал компилятора, который бы запретил такие действия или сделал их неправильно. Возможно теперь буду знать один - студию.

Я начинал с турбо си, и в одном из учебников даже разбирался код, меняющий строку (не помню для чего, помню, что экономил память). 

ИМХО Такие действия допустимы в плане ненарушения стандарта, но бессмыслены во всех остальных планах.

PM MAIL ICQ   Вверх
nickless
Дата 9.2.2007, 01:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



gcc 4.1.1 тоже вылетает

ЗЫ. но не всегда, только без оптимизации, с оптимизацией выводит оба раза "!!!"

Это сообщение отредактировал(а) nickless - 9.2.2007, 01:58


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
Anikmar
Дата 9.2.2007, 02:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(nickless @  9.2.2007,  01:50 Найти цитируемый пост)
gcc 4.1.1 тоже вылетает

ЗЫ. но не всегда, только без оптимизации, с оптимизацией выводит оба раза "!!!"

Чтож - значит уже два компилятора буду знать  smile 

Тем не менее - теоретически код правильный.

НО! ТАК ДЕЛАТЬ НЕ НАДО! (имхо)
PM MAIL ICQ   Вверх
ip127001
Дата 9.2.2007, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 164
Регистрация: 24.11.2006
Где: Omsk

Репутация: -2
Всего: -1



Цитата(vinter @  9.2.2007,  00:58 Найти цитируемый пост)
стандарт в глаза не видел
но верю Струструпу char *p = "111"; , и const char *p = "111"; одно и тоже  

а с какой стати
int *p=0;
const int *p=0;
одинаковыми стали...первый раз такое слышу!!!?

Добавлено @ 11:26 
они интерпритируются по разному...

Добавлено @ 11:32 
Код


     char *p="!!!";
     const char *p1="!!!";
       *(p+1)='?';-все ок!
      // *(p1+1)='?';-выводит ошибку т.к константа...
       cout<<p;-воводит !?!


     char *p="!!!";
     const char *p1="!!!";
-----------------------это разные вещи
--------------------
aqua currit et debere currere ut currere solebat
PM MAIL   Вверх
vinter
Дата 9.2.2007, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата
int *p=0;
const int *p=0;
одинаковыми стали...первый раз такое слышу!!!?


не перевирай мои слова, я это сказал только про char
Цитата
 char *p="!!!";
     const char *p1="!!!";
-----------------------это разные вещи


почитай топик нормально, мы уже выяснили, что кроме чисто сишного турбо С, и борланда компиляторы не дают так делать, т.к считают это КОНСТАНТОЙ и из этого следует, что это идентичные вещи и никаких разных интерпретаций!


--------------------
Мой блог
PM MAIL WWW   Вверх
Anikmar
Дата 9.2.2007, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(vinter @  9.2.2007,  13:08 Найти цитируемый пост)
почитай топик нормально, мы уже выяснили, что кроме чисто сишного турбо С, и борланда компиляторы не дают так делать, т.к считают это КОНСТАНТОЙ и из этого следует, что это идентичные вещи и никаких разных интерпретаций! 


Указатель никто и не пытался менять. Выясняли про собственно строку - в какую память он помещается.

В стандарте написано, что инициализированный указатель на строку преобразовывается в неконстантный указатель, за исключением случая, когда он объявлен как массив.

Компиляторы дают компилировать код, но вылетает сама программа при работе. Борланд ведет себя как положено в такой ситуации - строка меняется спокойно. Константный указатель или нет - это по барабану, никто не мешает сделать указатель неконстантным, присвоить ему значение проинициализированного строкой и попытаться поменять строку.

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

А по поводу к чему преобразовывается - посмотрел используя type_id. Указатель вида char*p = "jsjsjsj"; и просто char *p имеют одинаковый тип (по крайней мере в борланде).
PM MAIL ICQ   Вверх
ip127001
Дата 10.2.2007, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 164
Регистрация: 24.11.2006
Где: Omsk

Репутация: -2
Всего: -1



Цитата(Anikmar @  9.2.2007,  13:24 Найти цитируемый пост)
Указатель никто и не пытался менять. Выясняли про собственно строку - в какую память он помещается


а причем тут область памяти....ты не путаешь указатель на константу с константным указателем?
--------------------
aqua currit et debere currere ut currere solebat
PM MAIL   Вверх
MAKCim
Дата 10.2.2007, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



есть разница между целочисленной константой и литеральной
если есть целочисленная константа
Код

const int a = 5;

то компилятору не составит труда в качестве одного из операндов команды записать непосредственно 5, потому что это значение константы известно
код 
Код

const int a = 5;
int *b = const_cast<int*>(&a);
*b = 8;
int c = a;

может выглядеть так
Код

push ebp
mov ebp, esp
sub esp, 12
mov [ebp - 4], 5
lea eax, [ebp - 4]
mov [ebp - 8], eax
mov eax, [ebp - 8]
mov [eax], 8
mov [ebp - 12], 5

со строковыми литералами сложнее: непосредственно ее в команду никак не подставишь в отличие от целочисленной константы, поэтому она помещается в read-only секцию данных а в качестве операнда используется ее адрес в этой секции
для GCC это будет так для кода
Код

char *a = "UNIX is the great OS";
int b = 6;
a[b] = 'a';

Код

.section .rodata
string:
    .asciz "UNIX is the great OS"
...
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl -4(%ebp), $string
movl -8(%ebp), $6
movl -8(%ebp), %eax
movl -4(%ebp), %ebx
movl $61, (%ebx, %eax, )
push ebp
mov 

при этом при загрузке исполняемого файла и просмотре заголовков секций находится read-only секция и ее содержимое помещается в какую-то физическую страницу памяти, а в соответствующем этой странице элементе таблицы страниц сбрасывается флаг W, и дальнейшее обращение к ней с целью записи приводит к #PF 
А то, что какой-то Borland допускает изменение константной строки, то это говорит о "качестве" компилятора

Это сообщение отредактировал(а) MAKCim - 10.2.2007, 11:03


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Любитель
Дата 10.2.2007, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



На мой взгяд следовало бы вообще запретить
Код

char* s= "123";

только
Код

const char* s = "123"

 smile 


--------------------
PM MAIL ICQ Skype   Вверх
Anikmar
Дата 10.2.2007, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Стало быть так: если мы объявляем массив с инициализацией - его менять можно?
А если строку (которая тоже является массивом) то нельзя?
Если я пишу так
Код

char a[6] = {'H','e','l','l','o',0}; // Меняю как хочу - будет помещено в память со свободным доступом
char *b = "Hello"; // Менять нельзя - память только для чтения

a[1] = 'R'; // Так можно, ни у кого не возникнет вопросов
b[1] = 'R'; // Так нельзя - память только для чтения


Объясните где тут логика и чем строка отличается от массива?! Если я хочу инициализировать массив символов строкой - то в чем собственно проблема? Почему я потом не могу ее поменять?

Цитата(MAKCim @  10.2.2007,  11:00 Найти цитируемый пост)
А то, что какой-то Borland допускает изменение константной строки, то это говорит о "качестве" компилятора

Остаюсь при своем мнении - Борланд позволяет делать то, что не запрещено стандартом и он тут абсалютно прав.

Добавлено @ 12:32 
Цитата(Любитель @  10.2.2007,  11:58 Найти цитируемый пост)
только

const char* s = "123"



Делаю так - и все в порядке?
Код

const char* s = "123"
char *p = s;
p++;


Мы говорим не о возможности изменить УКАЗАТЕЛЬ, а о возможности изменить область памяти, на которую он ссылается!

PM MAIL ICQ   Вверх
MAKCim
Дата 10.2.2007, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(Anikmar @  10.2.2007,  12:31 Найти цитируемый пост)
Объясните где тут логика и чем строка отличается от массива?! Если я хочу инициализировать массив символов строкой - то в чем собственно проблема? Почему я потом не могу ее поменять?

строка - константна по своей природе и располагается в read-only области памяти (при выполнении программы)
в этом случае мы просто получаем ее адрес и изменить не можем
Код

char *a = "example";

Код

.section .rodata
string:
    .asciz "example"
...
pushl %ebp
movl %esp, %ebp
subl $4, %esp /* отводим 4 байта под указатель */
movl $string, -4(%ebp) /* собственно копируем указатель на строку */

а в этом создаем копию строки в стеке (read-write область памяти)
Код

char a[] = "example";

т. е грубо говоря компилятор генерирует приблизительно такой код
Код

.section .rodata /* read-only секция данных */
string:
    .asciz "example"
.text /* секция кода */
    pushl %ebp
    movl %esp, %ebp
    subl $8, %esp /* строка занимает 8 байт с нулем в конце */
    movl string, %eax /* копируем первые 4 символа */
    movl %eax, -8(%ebp)
    movl string + 4, %eax /* копируем оставшиеся символы */
    movl %eax, -4(%ebp)

и дальше можем изменять любой элемент a
конструкция же
Код

char a[8] = {'e', 'x', 'a', 'm', 'p', 'l', 'e', 0};

вообще банально проста (даже нет никакой символьной строки - просто символы)
Код

.text /* секция кода */
    pushl %ebp
    movl %esp, %ebp
    subl $8, %esp /* строка занимает 8 байт с нулем в конце */
    movl $0x6d617865, -8(%ebp) /* число 0x6d617865 в памяти располагается как 65 78 61 6D, что соответствует 'e' 'x' 'a' 'm' */
    movl $0x00656c70, -4(%ebp) /* 0x00656c70 -> 'p' 'l' 'e' '\0' */


Это сообщение отредактировал(а) MAKCim - 10.2.2007, 13:09


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
MAKCim
Дата 10.2.2007, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(Anikmar @  10.2.2007,  12:31 Найти цитируемый пост)
Остаюсь при своем мнении - Борланд позволяет делать то, что не запрещено стандартом и он тут абсалютно прав.

он не размещает константу (в данном случае символьную) в read-only секции данных - вот здесь его "хорошие" качества проявляются


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Anikmar
Дата 10.2.2007, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(MAKCim @  10.2.2007,  12:55 Найти цитируемый пост)
строка - константна по своей природе

Это из чего следует?

Я программист. Мне нужен строка флагов. Я могу ее создать двумя способами:

char Options[] = "AAABBBCCDDEEFF";

или

char *Options = "AAABBBCCDDEEFF";

Язык мне это разрешает, никакого запрета нет.

Если абстрагироваться от мысли, что строка, это обязательно текстовая константа, выводимая на экран и рассматривать ее как инициализированный массив char - то все в порядке.

Я не говорю, что так нужно делать. Я говорю о том, что теоретически можно. Но не нужно.

И в некоторых учебниках по си (конечно, старых) укаазывалось, что данный код необходимо применять с осторожностью, особенно, если указана опция соединять одинаковые строки.
Цитата(MAKCim @  10.2.2007,  12:55 Найти цитируемый пост)
а в этом создаем копию строки в стеке (read-write область памяти)

Вот тут для меня загадка. И это, называется оптимизацией? Зачем две одинаковые строки в памяти?

Резюме: мы такой баян растянули - что скоро остальные смеяться будут. Все равно каждый останется при своем мнении.
Я остаюсь при таком: Делать так не стоит - так как непринято, противоречит хорошему тону программирования и т.п. Но к ошибке приводить это также не должно.

PM MAIL ICQ   Вверх
MAKCim
Дата 10.2.2007, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(Anikmar @  10.2.2007,  13:15 Найти цитируемый пост)
Это из чего следует?

из того, что ты не можешь написать
Код

"bla-bla-bla"[0] = 'd';

равно как
Код

5 = a;
9.89 = b;

Цитата(Anikmar @  10.2.2007,  13:15 Найти цитируемый пост)
Вот тут для меня загадка. И это, называется оптимизацией? Зачем две одинаковые строки в памяти?

это пример, естественно оптимизация возможна, но факт остается фактом: в одном случае мы используем указатель на строку в read-only секции, в другом - мы ее создаем (а уж с оптимизацией или нет - зависит от компилятора)
Цитата(Anikmar @  10.2.2007,  13:15 Найти цитируемый пост)
Но к ошибке приводить это также не должно.

должно
Цитата(Anikmar @  10.2.2007,  13:15 Найти цитируемый пост)
Все равно каждый останется при своем мнении.

это не тот случай, где возможны мнения


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Anikmar
Дата 10.2.2007, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(MAKCim @  10.2.2007,  13:21 Найти цитируемый пост)
это не тот случай, где возможны мнения 

Да ладно уж. Мнения возможны всегда, даже если они неправильбные - это просто ошибочные мнения.

"bla-bla-bla"[0] - Такая конструкция запрещена синтаксисом самого языка.

Что не запрещено стандартом должно быть разрешено. Никто не давал права трактовать стандарт по своему усмотрению. Я ничего не нашел в стандарте по поводу запрета изменения строки. Конечно, этот способ скорее пережиток Си и MSDOS, но ничего криминального я не вижу. Моя память - что хочу то и делаю!


PM MAIL ICQ   Вверх
Страницы: (5) Все 1 2 [3] 4 5 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0643 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.