Гарантируется ли указатель на> определенное значение? - PullRequest
5 голосов
/ 12 февраля 2012

В C ++, когда я делаю new (или даже malloc), есть ли гарантия, что адрес возврата будет больше определенного значения? Потому что ... в этом проекте я считаю очень полезным использовать 0-1k в качестве перечисления. Но я бы не хотел этого делать, если возможно получить такое низкое значение. Мои единственные целевые системы - это 32- или 64-битные процессоры с окном OS / Linux и Mac.

Стандарт говорит что-нибудь об указателях? Windows или Linux говорят что-нибудь об их среде выполнения C и каков самый низкий адрес памяти (для оперативной памяти)?

-edit- я заканчиваю тем, что модифицировал мою перегрузку new, чтобы проверить, что адрес выше> 1k. Я вызываю std :: terminate, если это не так.

Ответы [ 5 ]

6 голосов
/ 12 февраля 2012

С точки зрения стандарта ничего нет.Но на самом деле, это зависит от целевой ОС, например, Windows резервирует первые 64 КБ памяти как ничейную землю (в зависимости от сборки она доступна только для чтения, иначе она помечается как PAGE_NOACCESS), в то время как она используетверхний 0x80000000 + для памяти ядра, но его можно изменить, см. this & this в MSDN.

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

4 голосов
/ 12 февраля 2012

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

2 голосов
/ 12 февраля 2012

Теоретически, нет - указатель даже не гарантированно будет> 0. Однако на практике рассматривается как целое число без знака (не забывайте, что указатель может иметь старший бит «1»), нет система, о которой я знаю, будет иметь значение указателя меньше чем около 1000. Но полагаться на это полагаться на «неопределенное поведение».

1 голос
/ 25 февраля 2012

Это очень зависит от платформы, поэтому я не рекомендую полагаться на такую ​​информацию, если у вас нет веских причин и вы не знаете о последствиях для переносимости, удобства обслуживания и т. Д.

NULL гарантированно всегда будет 0x0. Если я правильно помню, x86 резервирует первые 128 МБ адресного пространства как «эквивалентные NULL», так что действительные указатели не могут принимать значения в этом диапазоне. На x64 есть дополнительных адреса , с которыми вы не должны сталкиваться на практике, по крайней мере, на данный момент.

Что касается адресного пространства, зарезервированного для операционной системы, оно будет явно зависеть от ОС. В Linux деление пространства между ядром и пользователем настраивается в ядре, поэтому по крайней мере 3 разделения: 1-3 ГБ, 2-2 ГБ и 3-1 ГБ распространены в 32-разрядных системах. Вы можете найти более подробную информацию на kerneltrap .

1 голос
/ 12 февраля 2012

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

...