Russian Qt Forum

Программирование => С/C++ => Тема начата: IzoLda от Февраль 28, 2012, 06:47



Название: указатели или сами объекты...
Отправлено: IzoLda от Февраль 28, 2012, 06:47
есть экземпляр класса который имеет подобъекты такого же типа...объект и его подобъекты заполнены соответствующими данными,параметрами.чтобы обращаться именно к данным этого объекта мне необходимо в функцию передавать указатели на соответствующие объекты?а если передать сам объект,то не будет ли он с ним работать как с отдельным, независящим от других объектом???по ходу я не совсем понимаю разницу работы с указателями и самими объектами( или это копии объектов)...объясните пожалуйста!вообще советовали по мере возможности работать с указателями


Название: Re: указатели или сами объекты...
Отправлено: Bepec от Февраль 28, 2012, 07:04
дельфиг прыг акула кусь...

Почитай на досуге о классах С++.

А по теме: указатель на объект - это указатель на кусок памяти, где начинается объект. Чтобы с ним работать как с объектом, нужно его преобразовать к типу твоего класса. И усё получится.

А ещё лучше - приведи код, который у тебя не бачит, мы тебя поправим и, возможно, сумеем тебе пояснить ;)


Название: Re: указатели или сами объекты...
Отправлено: Disa от Февраль 28, 2012, 08:56
Как я понимаю, при передачи объекта на прямую всегда вызывается конструктор копирования и если он не перегружен, то копирование происходит полностью побитовое.

Для изменения значений переменной или объекта нужно передавать либо ссылку, либо указатель. Дальше уже зависит от стиля написания кода.

Google style guide рекомендует изменяемые значения передавать по указателю, а не изменяемые по константной ссылке(чтобы не занимать память копией объекта), чтобы при вызове функции можно всегда было понять какое значение меняется, а какое нет:

Код
C++ (Qt)
void foo(const myType& i, myType *j) {
 //do something
}
 
// вызов функции
myType i, j;
foo(i, &j);  // видно, что переменная j может быть изменена в ходе работы foo, а i - нет
 

Ну как говорится на вкус и цвет.
PS: Поправьте пж если не прав)


Название: Re: указатели или сами объекты...
Отправлено: Bepec от Февраль 28, 2012, 09:01
В принципе да, ты прав. Это хороший стиль программирования. Я им пока владею плохо ;)

Маленькое но - если объект содержит ссылки/указатели, то побитовое копирование безвозвратно может их утерять, изменить и будет большой бада-бум  ;)

PS чуть сумбурно, но именно так я себе всё и представляю. Турум пурум.


Название: Re: указатели или сами объекты...
Отправлено: Disa от Февраль 28, 2012, 10:06
Цитировать
Маленькое но - если объект содержит ссылки/указатели, то побитовое копирование безвозвратно может их утерять, изменить и будет большой бада-бум

А спасибо! Не знал, точнее пока на практике сам не реализовывал такие классы и поэтому не задумывался.


Название: Re: указатели или сами объекты...
Отправлено: Bepec от Февраль 28, 2012, 10:25
Даже не так.

Конструктор копирования не замечает ссылок, а тупо побитово копирует содержимое указателя/ссылки(адрес, а не содержимое). И будет 2 класса, которые используют один указатель/ссылку, что приведёт к неприятностям. Аля как у меня - БСОД после 30 отправки данных  ::) И фиг найдешь, если кто не поможет.


Название: Re: указатели или сами объекты...
Отправлено: Igors от Февраль 28, 2012, 10:49
по ходу я не совсем понимаю разницу работы с указателями и самими объектами( или это копии объектов)...объясните пожалуйста!вообще советовали по мере возможности работать с указателями
Это улавливается интуитивно, по мере накопления опыта. На первых порах отталкивайтесь от простого соображения: в С/С++ переменная - это ячейка памяти. Адрес этой ячейки определяется при объявлении переменной и никогда не меняется. Адрес можно записать а др ячейку - это и будет "указатель".  Неск примеров

Код
C++ (Qt)
int a = 1;        // "а" заняло свою ячейку (4 байта)
int * pa = &a;  // "pa" (сама тоже ячейка) содержит адрес "a" (указывает)
*pa = 2;        // изменили содержимое на что указывает "pa" (теперь a = 2)
pa = &b;       // а теперь "pa" указывает уже на что-то другое
 

 


Название: Re: указатели или сами объекты...
Отправлено: Tonal от Февраль 28, 2012, 10:50
Блин, народ, копирование поБАЙТОВОЕ а не поБИТОВОЕ.
В современных машинах нет простой возможности скопировать несколько битов из произвольного места в другое произвольное место, если эти числа не кратны размеру байта.
Все адреса в С/С++ указываются с точностью до БАЙТА. Размеры (sizeof) в С/С++ - в байтах.

По стандарту, дефолтное копирование реализовывает «почленное копирование» - это как будто ты вручную написал присвоение для всех полей.
Но в реале компилятор, когда реализует копирование простых структур, просто копирует байты источника в байты получателя.
Причём, в некоторых случаях между полями структуры могут быть дыры, и дыры могут быть между соседними структурами (в массиве), но компилятору это до фени - он будет копировать весь блок байтов от первого до последнего.

Соответственно, если какие-то поля - указатели, то они так же скопируются как и всё остальное.
Поэтому, если эти указатели в экземпляре источника и получателя указывали на разные объекты, то указатель получателя затрётся.
Это нужно учитывать и освобождать, или уменьшать счётчик использования, или добавлять в список свободных объектов...

П. С. Наследование и возможность переопределения копирования несколько усложняют картину, но не сильно. :)


Название: Re: указатели или сами объекты...
Отправлено: Bepec от Февраль 28, 2012, 10:54
Побитовое - побайтовое какая разница. Тут до низших уровней не спускаемся ;)


Название: Re: указатели или сами объекты...
Отправлено: IzoLda от Февраль 28, 2012, 11:37
спасибо большое всем за  доступно изложенные  ответы!!!будем наращивать опыт! :)


Название: Re: указатели или сами объекты...
Отправлено: Tonal от Февраль 28, 2012, 13:42
Побитовое - побайтовое какая разница. Тут до низших уровней не спускаемся ;)
Разницу я привёл - в С/С++ нельзя простыми спосовами скопирвать произвольную последовательность БИТОВ из произвольного места в другое, если размер последовательности и адреса не кратны 8. :)

Всегда лучше употреблять правильные и точные слова - потом меньше будет дыр в абстракциях. :)

П. С. Да, я зануда. :)


Название: Re: указатели или сами объекты...
Отправлено: Disa от Февраль 29, 2012, 08:53
Цитировать
Разницу я привёл - в С/С++ нельзя простыми спосовами скопирвать произвольную последовательность БИТОВ из произвольного места в другое, если размер последовательности и адреса не кратны 8.

Всегда лучше употреблять правильные и точные слова - потом меньше будет дыр в абстракциях.

Написал потому что эта фраза уже заезжана по ушам была))

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


Название: Re: указатели или сами объекты...
Отправлено: qt_user от Февраль 29, 2012, 10:07
а методы копировать не требуется. Нет?
нет, на сколько я помню, у методов глобальное время жизни они существуют еще до того как
как будет создан любой экземпляр данного класса, каждому методу передается скрытый указатель на
объект this


Название: Re: указатели или сами объекты...
Отправлено: Igors от Февраль 29, 2012, 11:23
Как я понимаю, сами биты копировать и не к чему, потому что размер класса всегда будет целое число байт, тк в плюсах всегда происходит выравнивание в памяти по размеру типа (а в случае с классом - кратным наибольшему из них),
Нет. Адрес каждого члена выравнивается на min(sizeof(member), align_size) где align_size задается компилятором и/или через #pragma

а методы копировать не требуется. Нет?
Прошу показать каким образом можно скопировать метод (ну хотя бы один)


Название: Re: указатели или сами объекты...
Отправлено: Bepec от Февраль 29, 2012, 12:04
Был один человек, он помоему побитовое копирование даже реализовывал :D Правда делал он это под linux ;)

А скопировать метод можно ЧУДЕСНЫМ способом :D


Название: Re: указатели или сами объекты...
Отправлено: mutineer от Февраль 29, 2012, 12:09
а методы копировать не требуется. Нет?
Прошу показать каким образом можно скопировать метод (ну хотя бы один)

Ctrl+C / Ctrl+V же ;D


Название: Re: указатели или сами объекты...
Отправлено: Tonal от Февраль 29, 2012, 13:50
Побитовое копирование реализуется битовыми операциями довольно просто, но нудно. Да и в большинстве случаев оно не нужно. :)

А скопировать метод вполне можно, если архитектура машины Фон Неймоновская (http://ru.wikipedia.org/wiki/%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D1%84%D0%BE%D0%BD_%D0%9D%D0%B5%D0%B9%D0%BC%D0%B0%D0%BD%D0%B0) (для большинства современных это ещё так).
В этом случае код размещается в той же памяти что и данные. Значит для того, чтобы скопировать метод нужно узнать где он лежит в памяти и его размер.
Где лежит узнать элементарно - в С/С++ взятие адреса функции штатная операция.
А вот размер в общем случае не получишь. Можно только разными компиляторозависимыми хаками. Но почти в каждом конкретном случае какой-то путь можно найти. :)


Название: Re: указатели или сами объекты...
Отправлено: mutineer от Февраль 29, 2012, 13:56
Побитовое копирование реализуется битовыми операциями довольно просто, но нудно. Да и в большинстве случаев оно не нужно. :)

А скопировать метод вполне можно, если архитектура машины Фон Неймоновская (http://ru.wikipedia.org/wiki/%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D1%84%D0%BE%D0%BD_%D0%9D%D0%B5%D0%B9%D0%BC%D0%B0%D0%BD%D0%B0) (для большинства современных это ещё так).
В этом случае код размещается в той же памяти что и данные. Значит для того, чтобы скопировать метод нужно узнать где он лежит в памяти и его размер.
Где лежит узнать элементарно - в С/С++ взятие адреса функции штатная операция.
А вот размер в общем случае не получишь. Можно только разными компиляторозависимыми хаками. Но почти в каждом конкретном случае какой-то путь можно найти. :)

А куда его копировать? Страницы, в которых лежит код, приложению для записи недоступны. А страницы с данными во всех современных операционках недоступны для выполнения. Да и за чтение из страниц кода операционка может по рукам надавать


Название: Re: указатели или сами объекты...
Отправлено: Igors от Февраль 29, 2012, 14:17
А куда его копировать? Страницы, в которых лежит код, приложению для записи недоступны. А страницы с данными во всех современных операционках недоступны для выполнения. Да и за чтение из страниц кода операционка может по рукам надавать
Ну сразу и лапки кверху  :)  А садами-огородами, напр через PrestoChangoSelector? (потом ее как-то по-другому назвали).


Название: Re: указатели или сами объекты...
Отправлено: BRE от Февраль 29, 2012, 16:32
А куда его копировать? Страницы, в которых лежит код, приложению для записи недоступны. А страницы с данными во всех современных операционках недоступны для выполнения. Да и за чтение из страниц кода операционка может по рукам надавать
Подумай, как выполняются эксплоиды.


Название: Re: указатели или сами объекты...
Отправлено: mutineer от Февраль 29, 2012, 17:12
А куда его копировать? Страницы, в которых лежит код, приложению для записи недоступны. А страницы с данными во всех современных операционках недоступны для выполнения. Да и за чтение из страниц кода операционка может по рукам надавать
Подумай, как выполняются эксплоиды.

Через дыры в этих механизмах защиты, не?


Название: Re: указатели или сами объекты...
Отправлено: BRE от Февраль 29, 2012, 17:30
Через дыры в этих механизмах защиты, не?
Они используют дыры в приложениях, а ОС просто позволяют это сделать. Т.е. большинство современных ОС позволяют выполнять код и в сегменте данных и в сегменте стека.
Конечно, для некоторых ОС есть некоторые патчи запрещающие это, но это - опция, которая как правило по умолчанию не включена.



Название: Re: указатели или сами объекты...
Отправлено: mutineer от Февраль 29, 2012, 17:50
Конечно, для некоторых ОС есть некоторые патчи запрещающие это, но это - опция, которая как правило по умолчанию не включена.

Это какие-то старые данные. http://en.wikipedia.org/wiki/Data_Execution_Prevention
Цитировать
DEP was introduced on Linux in 2004 (kernel 2.6.8[2]), on Windows in 2004 with Windows XP Service Pack 2,[3] while Apple introduced DEP in 2006.[1] (When they moved to x86)
Какие еще патчи, если в ядрах прям функция есть?
К тому же на венде она по умолчанию включена в режим защиты определенного круга системных приложений (а не выключена)


Название: Re: указатели или сами объекты...
Отправлено: BRE от Февраль 29, 2012, 17:53
К тому же на венде она по умолчанию включена в режим защиты определенного круга системных приложений (а не выключена)
Это я не про венду говорил, а про linux.


Название: Re: указатели или сами объекты...
Отправлено: mutineer от Февраль 29, 2012, 18:03
К тому же на венде она по умолчанию включена в режим защиты определенного круга системных приложений (а не выключена)
Это я не про венду говорил, а про linux.

Сори, не включил либастрал. Источником данных не поделишься? А то ниче нагуглить не могу

Нагуглил вот, что в MacOS X и RHEL 3 update 3 и позже включено по умолчанию


Название: Re: указатели или сами объекты...
Отправлено: BRE от Февраль 29, 2012, 18:11
Сори, не включил либастрал. Источником данных не поделишься? А то ниче нагуглить не могу
Поищи так: linux защита от переполнения стека

Нагуглил вот, что в MacOS X и RHEL 3 update 3 и позже включено по умолчанию
А на обычных ядрах обычных дистрибутивов?


Название: Re: указатели или сами объекты...
Отправлено: mutineer от Февраль 29, 2012, 18:15
Нагуглил вот, что в MacOS X и RHEL 3 update 3 и позже включено по умолчанию
А на обычных ядрах обычных дистрибутивов?

Чем у RHEL не обычное ядро? в "обычном" ядре эта функция присутствует с 2.6.8. В Ubuntu с 9.04 или 9.10 включено по умолчанию
Даже в ведроиде есть и работает

Только это не "защита от переполнения стека" называется


Название: Re: указатели или сами объекты...
Отправлено: BRE от Февраль 29, 2012, 18:18
Чем у RHEL не обычное ядро? в "обычном" ядре эта функция присутствует с 2.6.8. В Ubuntu с 9.04 или 9.10 включено по умолчанию
Потому, что пропатчено.

Только это не "защита от переполнения стека" называется
Ты так в гугле набери и с начала начни читать.


Название: Re: указатели или сами объекты...
Отправлено: mutineer от Февраль 29, 2012, 18:20
Чем у RHEL не обычное ядро? в "обычном" ядре эта функция присутствует с 2.6.8. В Ubuntu с 9.04 или 9.10 включено по умолчанию
Потому, что пропатчено.

Ок, если тебе так удобнее, то пусть будет пропатчено. Пропатчено, правда, аж в 2004 году и с тех пор этот патч есть в основном ядре, ну да ладно...

https://www.google.com/search?client=opera&rls=ru&q=Data+Execution+Prevention+linux&sourceid=opera&ie=utf-8&oe=utf-8#q=Data+Execution+Prevention+linux&hl=ru&client=opera&hs=Dr6&rls=ru&prmd=imvns&ei=cj5OT4nHGIzP4QTYvbTaAg&start=10&sa=N&fp=1&biw=1075&bih=808&bav=on.2,or.r_gc.r_pw.r_cp.,cf.osb&cad=b

http://en.wikipedia.org/wiki/NX_bit


Название: Re: указатели или сами объекты...
Отправлено: BRE от Февраль 29, 2012, 18:38
Ок, если тебе так удобнее, то пусть будет пропатчено. Пропатчено, правда, аж в 2004 году и с тех пор этот патч есть в основном ядре, ну да ладно...
Еще что интересного нагуглил?

Вот смотри интересные статьи:
http://www.securitylab.ru/analytics/406154.php
http://www.insidepro.com/kk/063/063r.shtml


Название: Re: указатели или сами объекты...
Отправлено: Tonal от Март 01, 2012, 12:21
А скопировать метод вполне можно, если архитектура машины Фон Неймоновская (http://ru.wikipedia.org/wiki/%D0%90%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0_%D1%84%D0%BE%D0%BD_%D0%9D%D0%B5%D0%B9%D0%BC%D0%B0%D0%BD%D0%B0) (для большинства современных это ещё так).
...
А куда его копировать? Страницы, в которых лежит код, приложению для записи недоступны. А страницы с данными во всех современных операционках недоступны для выполнения. Да и за чтение из страниц кода операционка может по рукам надавать
Это уже отход от классической архитектуры. :)
А зачем это делать - вопроса не было. Был вопрос можно ли и как, если можно. :)
На вопрос можно ли - ответ - нет, если использовать только средства языка С/С++.
Но скорее всего можно, если знаешь архитектуру, ОС, компилятор+линкер.

Вопрос зачем опять же зависит от задачи.
Например пакеры и многие защитки в винде построены на возможности копировать код (распоковка/расшифровка по требованию).
В сущности они подменяют стандартный загрузчик ОС. Вроде бы это можно сделать в linux штатными методами, но даже при наличии штатных методов для реализации загрузчика нужно уметь заполнить некоторую область памяти инструкциями и отметить её выполняемой...

Другой пример - в основе оконной библиотеки OWL (http://ru.wikipedia.org/wiki/Object_Windows_Library) лежала возможность выполнять код из кучи - для каждого экземрляра окна создавался небольшой переходник который регистрировался как оконная функция WinApi.
Если не ошибаюсь, то же делается и в VCL (http://ru.wikipedia.org/wiki/VCL), WTL (http://ru.wikipedia.org/wiki/WTL), MFC (http://ru.wikipedia.org/wiki/MFC).
Хотя две последние детально не ковырял, он это один из самых быстрых способов использовать оконное WinApi в объектных библиотеках. :)

Так что причины могут быть. Но чисто средствами С/С++ это не решается. :)