Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557

Инкрементация указателя по членам класса

22.12.2016, 20:25. Показов 915. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вот такая задачка у меня попалась на тестировании: "Корректен ли данный код? Если да, то что будет выведено на экран? Аргументируйте свой ответ. "
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
struct C
{
    char a, b;
};
 
int main()
{
    C c;
    c.a = 'x';
    c.b = 'y';
    char* pc = &c.a;
    pc++;
    std::cout << *pc;
}
Я ответил, что результат не определен из за выравнивания в классе и инкрементация указателя может указывать на не корректную память. Следовательно, может вывести как 'y' так и мусор.
Но, вот уже дома проверил - выводит всегда 'y'. Это такое поведение по стандарту? Или тут что другое.
2
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.12.2016, 20:25
Ответы с готовыми решениями:

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

Создание указателя на экземпляр класса, описанного после объявления указателя
Здравствуйте! Проблема в том, что нужно сделать так: class A{ public: B* b = nullptr; }; class B{ public:

Доступ к членам класса класса
Всем привет. Вобщем есть базовый класс, и два производных. Пользователь вводит координаты нужно проверить факт пересечения одной фигуры с...

19
114 / 112 / 62
Регистрация: 15.03.2013
Сообщений: 561
Записей в блоге: 5
22.12.2016, 21:07
Нашел вот такую инфу в интернете
Выравниваются в памяти поля по границе кратной своему же размеру. То есть 1-байтовые поля не выравниваются, 2-байтовые — выравниваются на чётные позиции, 4-байтовые — на позиции кратные четырём и т.д.
1
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
23.12.2016, 00:31  [ТС]
Из всего этого делаем вывод что если одинаковые типы в классе идут один за другим, то по ним можно спокойно пробегаться указателем.

Добавлено через 4 минуты
Даже в private получается залесть:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct C
{
    short a;
private:
    short b = 20;
};
 
int main()
{
    C c;
    c.a = 2;
    short* p = &c.a;
    p++;
    std::cout << "p = " << *p << "\n"; // 20
}
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
23.12.2016, 01:29
Цитата Сообщение от notAll Посмотреть сообщение
Даже в private получается залесть
Для разных секций нет гарантии порядка. Так что этот код потенциально может породить выход за пределы объекта.
1
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
23.12.2016, 01:33
DrOffset, а откуда такое утверждение? после компиляции нету секций и разделения на права доступа. Инициализация полей будет сверху вниз с объявления класса в любом случаи
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
23.12.2016, 01:38
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
а откуда такое утверждение? после компиляции нету секций и разделения на права доступа
При чем тут "после компиляции нет секций"?
Еще раз: нет гарантии порядка для переменных в разных секциях. Это значит, что в результате (в зависимости от реализации компилятора) может получиться как объект с лэяутом
Code
1
2
<a>
<b>
так и с лэяутом
Code
1
2
<b>
<a>
так вот, во втором случае, получая адрес а, а затем инкрементируя его, мы вылетаем за границы объекта.
1
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
23.12.2016, 01:42
DrOffset, так я и интересуюсь откуда у вас эта информация? Почему компиляторы могут изменить порядок класс-членом не "сверху-вниз" ?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
23.12.2016, 01:50
rikimaru2013,
Цитата Сообщение от 9.2/12
Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).
Добавлено через 2 минуты
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
так я и интересуюсь откуда у вас эта информация?
Ты не интересуешься, а споришь, причем безосновательно.

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Инициализация полей будет сверху вниз с объявления класса в любом случаи
Порядок инициализации полей к рассматриваемому вопросу отношения не имеет.

Добавлено через 4 минуты
В новых черновиках эта цитата в 13м пункте, а не в 12. На всякий случай говорю.
7
 Аватар для Nosey
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
23.12.2016, 01:51
DrOffset, А зачем такое поведение в стандарт ввели, это дает какую-то возможность компиляторам?
0
23.12.2016, 01:54

Не по теме:

Nosey, я тоже самое спрашивал - но меня оклеветали, что я спорю) :cry:

0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
23.12.2016, 02:06
Цитата Сообщение от Nosey Посмотреть сообщение
А зачем такое поведение в стандарт ввели, это дает какую-то возможность компиляторам?
Насколько я знаю, в стандарте оно всегда было.
Про "зачем ввели" - свечку не держал (это значит, что далее идет мое личное мнение, которое может не соответствовать истине), но, возможно, это сделано чтобы дать возможность оптимизировать размер классов. В пределах одной секции порядок будет неизменен, но разные секции теоретически можно переставить местами в памяти, чтобы получить более компактный размер. Но, честно говоря, я не назову сейчас ни одного компилятора, который бы это делал на практике.
2
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.12.2016, 12:05
Цитата Сообщение от ящюр Посмотреть сообщение
Нашел вот такую инфу в интернете
ложь.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12938 / 6805 / 1821
Регистрация: 18.10.2014
Сообщений: 17,224
23.12.2016, 12:16
Цитата Сообщение от notAll Посмотреть сообщение
Я ответил, что результат не определен из за выравнивания в классе и инкрементация указателя может указывать на не корректную память. Следовательно, может вывести как 'y' так и мусор.
Совершенно правильный ответ. Поведение такого кода будет не определено.

Цитата Сообщение от notAll Посмотреть сообщение
Но, вот уже дома проверил - выводит всегда 'y'. Это такое поведение по стандарту? Или тут что другое.
Так в вы чего ожидали? Что на мониторе загорятся большие красные буквы "поведение не определено"? Неопределенное поведение можно проявлять себя в том числе и как "работающий" код. Понятно, что на практике поля класса могу быть расположены в памяти компактно и вести себя фактически как элементы одного массива. Но это не меняет того факта, что язык формально не поддерживает такой адресной арифметики и поведение не определено.

Цитата Сообщение от notAll Посмотреть сообщение
Из всего этого делаем вывод что если одинаковые типы в классе идут один за другим, то по ним можно спокойно пробегаться указателем.
"Можно" в смысле "у меня все работало и у Васи Косого из второго подъезда, говорят, тоже работало".

С точки зрения языка ничего подобного делать не разрешается.
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.12.2016, 12:20
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Совершенно правильный ответ. Поведение такого кода будет не определено.
с фигали? оба чара в рамках одной секции будут идти друг за другом вплотную.
возможное выравнивание будет по границе однородных членов.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
С точки зрения языка ничего подобного делать не разрешается.
язык никому ничего не запрещает.
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
23.12.2016, 12:30
Цитата Сообщение от notAll Посмотреть сообщение
Вот такая задачка у меня попалась на тестировании:
Надо было сразу на подобный глупый вопрос спросить:
А в скольких местах подобная конструкция используется в вашем production коде?
Ответ "много где" - нахрена мне нужно поддерживать ваш быдлокод?
Ответ "нигде" - нахрена мне нужно это тогда знать наизусть?
2
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12938 / 6805 / 1821
Регистрация: 18.10.2014
Сообщений: 17,224
23.12.2016, 12:53
Цитата Сообщение от hoggy Посмотреть сообщение
с фигали? оба чара в рамках одной секции будут идти друг за другом вплотную.
В С++ "друг за другом вплотную" идут только элементы одного массива. Все остальные "будут идти друг за другом вплотную" - не более чем особенности/совпадения/случайности конкретной реализации, к языку С++ никакого отношения не имеющие.

В язык С++ адресная арифметика определена только среди элементов одного массива. Никакой другой адресной арифметики в С++ нет.

Цитата Сообщение от hoggy Посмотреть сообщение
возможное выравнивание будет по границе однородных членов.
Язык С++ не дает никаких гарантий на тему того, где и как будут располагаться padding bytes в классе. Выравнивание в данном случае (и в любом другом случае) возможно где угодно и в неограниченных количествах.

Цитата Сообщение от hoggy Посмотреть сообщение
язык никому ничего не запрещает.
Речь идет о легальности конструкции и определенности поведения.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.12.2016, 13:21
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
В С++ "друг за другом вплотную" идут только элементы одного массива. Все остальные "будут идти друг за другом вплотную" - не более чем особенности/совпадения/случайности конкретной реализации, к языку С++ никакого отношения не имеющие.
такое поведение вполне объясняется банальным здравым смыслом.
не знаю ни один компилятор, который втыкал бы дырки между однородными членами.
тем паче, что стандарт позволяет доступ к чару по неровному адресу.
вставлять между ними дырки - это какой то бред.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12938 / 6805 / 1821
Регистрация: 18.10.2014
Сообщений: 17,224
23.12.2016, 13:32
Цитата Сообщение от hoggy Посмотреть сообщение
тем паче, что стандарт позволяет доступ к чару по неровному адресу.
вставлять между ними дырки - это какой то бред.
Дело тут не в том, чтобы вставлять или не вставлять между ними дырки, а в том, что такой фичи, как итерирование/адресная арифметика по независимым полям класса в языке С++ просто нет.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.12.2016, 13:37
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Дело тут не в том, чтобы вставлять или не вставлять между ними дырки, а в том, что такой фичи, как итерирование/адресная арифметика по независимым полям класса в языке С++ просто нет.
зато есть доступ к памяти, и возможность заинкрементить обычный указатель на данные.
стандарт не объявляет подобную ситуацию UB.
насколько мне известно, он просто её не описывает.
но по косвенным признакам, которые стандарт описывает,
можно допустить, что подобный хак - не есть ill formed,
а значит не есть UB
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
23.12.2016, 14:42
Цитата Сообщение от MrGluck Посмотреть сообщение
Ответ "много где" - нахрена мне нужно поддерживать ваш быдлокод?
Дык это любимый сишниками каламбур типизации. Вероятно, достался в нагрузку к библиотекам на "самом лучшем" языке.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.12.2016, 14:42
Помогаю со студенческими работами здесь

Доступ к членам класса
Объект класса не может получить доступ к своим переменным?

Доступ к членам класса
Есть два класса: #include &quot;stdafx.h&quot; #include &lt;iostream&gt; using namespace std; class CPerson { /*закрытые члены*/ private:...

Доступ к приватным членам класса
Хочу я иметь доступ к приватному члену класса. Зачем это надо - за рамками данной темы и не обсуждается. Вот упрощенный код класса: ...

Обращение к элементам, членам класса
Здравствуйте! Мне нужно выполнить задания из меню (в коде программы), но я не могу понять как обраться в функции к NodeElement *cur и к...

Доступ к private членам класса
Почему при таком объявлении не работает оператор вывода, по идее он же объявлен как друг класса и должен иметь доступ к членам этого...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru