![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
Iron Bug |
![]()
Сообщение
#21
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
Вообще вот цитата из википедии: A data segment is a portion of virtual address space of a program, which contains the global variables and static variables that are initialized by the programmer.Т.е. они называют сегментом данных то что вы называете сегментом кода. Непонятно кто прав.. ты дальше-то читай википедию. там в целом правильно написано. кусок константных данных в коде они там называют Rodata. а перезаписываемые данные, соответственно, сегментом данных. реализации распределения некоторых переменных в языках высокого уровня могут отличаться. какие-то компиляторы оптимизируют константы и помещают их в код, какие-то - нет, и оставляют их в сегменте данных. в любом случае есть основная разница: сегмент кода не доступен для записи, сегмент данных и стек - это всё, что меняется. если хочешь глубже понять принципы - читай про ассемблер. если тебя интересует конкретная реализация - ты можешь просто посмотреть адреса в отладчике, и сравнить с регистрами. в архитектуре PC сегмент кода - это то, куда указывает CS. стек - SS. а данные, как правило, помещаются либо в DS, либо в ES (но там могут быть и адреса других сегментов, если идёт обработка константных данных, например). однако, в дебажном варианте распределение немного другое, там есть ловушки для нулевых смещений и выхода за границы массивов, отсутствие оптимизации размещения и всяческие компиляторные вставки для отладки. там может быть немного другое распределение. Сообщение отредактировал Iron Bug - 23.12.2011, 7:47 |
|
|
BRE |
![]()
Сообщение
#22
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
если тебя интересует конкретная реализация - ты можешь просто посмотреть адреса в отладчике, и сравнить с регистрами. в архитектуре PC сегмент кода - это то, куда указывает CS. стек - SS. а данные, как правило, помещаются либо в DS, либо в ES (но там могут быть и адреса других сегментов, если идёт обработка константных данных, например). однако, в дебажном варианте распределение немного другое, там есть ловушки для нулевых смещений и выхода за границы массивов, отсутствие оптимизации размещения и всяческие компиляторные вставки для отладки. там может быть немного другое распределение. Это было актуально во времена ??-DOS работающей в реальном режиме. Сейчас большинство ОС работает в защищенном режиме (в сегментных регистрах храняться уже не адреса, а дескрипторы сегментов из специальных дескрипторных таблицах GDT или LDT), да и процессы все выполняются в flat-режиме, в котором все сегменты (код, данные, стек) настраиваются на одни и те жи адреса виртуальной памяти. Защита выполняется на уровне страниц памяти (защита на уровне сегментов не используется вообще - для скорости). Сообщение отредактировал BRE - 23.12.2011, 9:18 |
|
|
rp80 |
![]()
Сообщение
#23
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
rp80, стек то никуда не девается. А то, что ты правильно выводишь якобы - это уже мусор, одна ко по чистой случайности этот мусор пока ещё соответствует тому, что в него поместили внутри вложенного блока попробуй вот так
Ничего не меняется, какие переменные потом не определяй, все равно правильно работает ) |
|
|
Алексей1153 |
![]()
Сообщение
#24
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2941 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
rp80, значит компилятор разместил переменную не так, как я подумал ) Но это неважно, суть ты понял, я полагаю
|
|
|
Iron Bug |
![]()
Сообщение
#25
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
(в сегментных регистрах храняться уже не адреса, а дескрипторы сегментов из специальных дескрипторных таблицах GDT или LDT а, ну да. тут ещё оттуда придётся тащить данные. у дров есть функция взятия физического адреса, а вот в юзерспейсе я чота не помню, есть такая фича или нет... я-то живу в основном в кернеле ![]() в общем, тогда лучше не пытаться гадать, а взять какой-нить стандарт ELF или вендозные спецификации и почитать про конкретные оси и конкретные компиляторы. впрочем, от этого разницы никакой не будет. для программиста интерес представляет размер стека, оптимизация работы с указателями и решение использования стека или кучи. я в юзерских программах не парюсь и использую кучу. ибо она практически не ограничена и чаще всего скорость доступа совершенно не критична, так как юзерские программы обычно и без того тормозят из-за вывода и экономия на адресах не даёт никакого эффекта. |
|
|
BRE |
![]()
Сообщение
#26
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
rp80 |
![]()
Сообщение
#27
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
я в юзерских программах не парюсь и использую кучу. ибо она практически не ограничена и чаще всего скорость доступа совершенно не критична, так как юзерские программы обычно и без того тормозят из-за вывода и экономия на адресах не даёт никакого эффекта. Я бы тоже не стал лазить в такие дебри. Но стал тут разбираться с копированием объектов и вот такое поведение непонятно.
Выводит: 0 - 123 - Segmentation fault. Т.е. скопировался как надо только указатель на динамически выделенную память. Сообщение отредактировал rp80 - 23.12.2011, 10:41 |
|
|
Алексей1153 |
![]()
Сообщение
#28
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2941 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
rp80, как разберёшься с указателями на массивы, открой для себя std-контейнеры )
а в данном случае тебе нужно переопределить оператор присваивания (и конструктор по умолчанию) для корректного копирования |
|
|
rp80 |
![]()
Сообщение
#29
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
rp80, как разберёшься с указателями на массивы, открой для себя std-контейнеры ) а в данном случае тебе нужно переопределить оператор присваивания (и конструктор по умолчанию) для корректного копирования Так в том то и дело, что по идее копирование по умолчанию должно копировать почленно. И если мы потом поменяем значение по одному указателю, должно поменяться и второе |
|
|
BRE |
![]()
Сообщение
#30
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
Т.е. скопировался как надо только указатель на динамически выделенную память. Кому надо? Компилятор сделал то что ты ему сказал. Сделал бинарную копию a2 равную a1 (потеряв при этом указатель на область памяти pi - утечка). Указатель a2.str как показывал "в никуда", так и показывает - отсюда вылет программы. Все ожидаемо. И если мы потом поменяем значение по одному указателю, должно поменяться и второе Так и есть. Там где ты меняешь что-то по указателю, там и меняется (a1.pi[ 0 ] и a2.pi[ 0 ] ). |
|
|
![]() ![]() ![]() |
![]() |
Текстовая версия | Сейчас: 16.2.2025, 20:27 |