Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
daslex
1291 / 535 / 177
Регистрация: 02.08.2011
Сообщений: 2,756
#1

Две разных переменных по одному адресу - C++

14.12.2015, 02:16. Просмотров 647. Ответов 12
Метки нет (Все метки)

Что это за юмор такой?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <new>
 
using namespace std;
 
int main() {
 
   double *a= new double{200};
   int *b = new(a) int{256};
 
   cout << a << " == " << b << "\n";
   cout << *a << " == " << *b << "\n";
 
   delete a;
}
output:
адрес один, но на нем как будто 2 независимых значения.
200==256
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.12.2015, 02:16
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Две разных переменных по одному адресу (C++):

Две экспортные функции по одному адресу
Здравствуйте. Использую для экспорта: extern &quot;C&quot; __declspec(dllexport)...

Определить принадлежат ли одному и тому же листу две заданные страницы
Страницы. Страницы в книгах обычно нумеруются натуральными числами 1, 2, 3, ......

Сравнение переменных разных типов
Здравствуйте. Столкнулся с проблемой не совпадения типов данных. Есть...

Адреса двух разных переменных одинаковы
Добрый день! Пытаюсь вывести в Memo1 адреса переменных: int a=5555; int...

В чём отличие разных способов объявления переменных?
в чем отличие int a(2); от int a=2; И как писать правильней

Как передать в функцию две переменных?
Хочу написать простейших калькулятор через условия (Если пользователь выбрал 1,...

12
nonedark2008
1022 / 762 / 210
Регистрация: 28.07.2012
Сообщений: 2,118
14.12.2015, 02:31 #2
daslex, типы разные, интерпретация данных тоже разная.

Добавлено через 2 минуты
То что ты проделал равносильно фокусу с
C++
1
2
3
4
union A{
  double a;
  int b;
}
1
Croessmah
++Ͻ
14161 / 8086 / 1513
Регистрация: 27.09.2012
Сообщений: 19,929
Записей в блоге: 3
Завершенные тесты: 1
14.12.2015, 02:32 #3
double - 8 Байт, а int, скорее всего 4, поэтому перезаписываются только старшие байты значения double. Поменяйте int на int64_t и увидите разницу
2
nonedark2008
1022 / 762 / 210
Регистрация: 28.07.2012
Сообщений: 2,118
14.12.2015, 02:36 #4
Цитата Сообщение от Croessmah Посмотреть сообщение
Поменяйте int на int64_t и увидите разницу
Разница и так видна, если смотреть это дело в отладчике.
cout в стандартном режиме любит все округлять.
1
Croessmah
++Ͻ
14161 / 8086 / 1513
Регистрация: 27.09.2012
Сообщений: 19,929
Записей в блоге: 3
Завершенные тесты: 1
14.12.2015, 02:39 #5
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Разница и так видна
как видите, не вооруженным глазом не видна разве что вывод настроить.
Ну а с int64_t видно сразу
1
nonedark2008
14.12.2015, 02:45
  #6

Не по теме:

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

0
daslex
1291 / 535 / 177
Регистрация: 02.08.2011
Сообщений: 2,756
14.12.2015, 03:10  [ТС] #7
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Разница и так видна, если смотреть это дело в отладчике.
Ну и что я там должен увидеть. В отладчике VS я вижу тоже самое, что я вижу и без отладчика.

Цитата Сообщение от Croessmah Посмотреть сообщение
Ну а с int64_t видно сразу
аналогично.

Ну я понял, что интерпретация разная. Что старшие байты перезаписываются.
Только назрел дополнительный вопрос. Каким большим должно быть число, чтобы на платформе x86 изменением данных в double изменились обе переменные?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <new>
 
using namespace std;
 
int main() {
 
    double *a = new double{ 200 };
    int *b = new(a) int{ 256 };
 
    cout << a << " == " << b << "\n";
    cout << *a << " == " << *b << "\n";
 
    size_t i = -1;
 
    *b += i;
 
    cout << i << '\n';
 
    cout << a << " == " << b << "\n";
    cout << *a << " == " << *b << "\n";
 
    delete a;
    cin.get();
}
*a осталось каким было. а не похоже, что должно было.

Добавлено через 5 минут
хотя на x64 лучше. Там же тоже 15 значащих после точки.
изменением *b, тип которого double, затронулось *a, тип которого int
вот правильная формулировка'
0
Croessmah
++Ͻ
14161 / 8086 / 1513
Регистрация: 27.09.2012
Сообщений: 19,929
Записей в блоге: 3
Завершенные тесты: 1
14.12.2015, 03:26 #8
Цитата Сообщение от daslex Посмотреть сообщение
*a осталось каким было. а не похоже, что должно было.
http://rextester.com/DOJN12148

Ну и намного эффективнее будет поменять *a = 343 ;

Добавлено через 4 минуты
Цитата Сообщение от daslex Посмотреть сообщение
аналогично.
http://rextester.com/ZJU95526
1
nonedark2008
1022 / 762 / 210
Регистрация: 28.07.2012
Сообщений: 2,118
14.12.2015, 03:46 #9
Цитата Сообщение от daslex Посмотреть сообщение
В отладчике VS я вижу тоже самое, что я вижу и без отладчика.
А я вижу в указателе на double 200.00000000000000 до изменения второго и 200.00000000000728 после инициализации данных по второму указателю.
1
daslex
1291 / 535 / 177
Регистрация: 02.08.2011
Сообщений: 2,756
14.12.2015, 03:57  [ТС] #10
А вот ничего и не понятно.
Я понимаю, что такое замещение. Но не очень понимаю маленькой, может быть никому не нужной детали.
Пишите мне, что старшие байты перезаписываются. Хорошо, думаю, если перезаписывать старшие байты, то при достаточно большом числе, рано или поздно байты из типа double должны наползти на байты типа int. На сайте в онлайн я это увидел. Да, там много "единичек" изменилось. Но в двух компиляторах в оффлайн числа почти остались неизменны. В VS x86 и x64 отладчик отдаёт одно и то же. Вот это уже не так уж и понятно.

на рис. clang 3.7 и VS2015/ x - это *a до изменения.
0
Миниатюры
Две разных переменных по одному адресу   Две разных переменных по одному адресу  
nonedark2008
1022 / 762 / 210
Регистрация: 28.07.2012
Сообщений: 2,118
14.12.2015, 04:32 #11
Цитата Сообщение от daslex Посмотреть сообщение
Пишите мне, что старшие байты перезаписываются.
Тут скорее перезаписываются не старшие байты, а младшие.
В типе double первые 52 бита отводятся под мантиссу, значит int будет попадать только на мантиссу.
Думаю, если вкурить вики, вы сможете все посчитать.

Добавлено через 19 минут
Записывая в double значение 200 мы получаем порядок 1030, с таким порядком мы получаем множитель 2^7.
Значит изменение мантиссы на единицу приведет к изменению значения вещественного числа на величину http://www.cyberforum.ru/cgi-bin/latex.cgi?{2}^{-45}. Int охватывает только первые 32 бита мантиссы, так что сильных изменений на значение вещественного числа мы оказать не сможем.
1
rat0r
18 / 26 / 5
Регистрация: 16.02.2018
Сообщений: 197
07.03.2018, 13:02 #12
Цитата Сообщение от daslex Посмотреть сообщение
Что это за юмор такой?
Называется undefined behavior.
0
Croessmah
++Ͻ
14161 / 8086 / 1513
Регистрация: 27.09.2012
Сообщений: 19,929
Записей в блоге: 3
Завершенные тесты: 1
07.03.2018, 13:04 #13
rat0r, Вы некрофил?
0
07.03.2018, 13:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.03.2018, 13:04
Привет! Вот еще темы с решениями:

Две части программы на разных компиляторах
Не знаю, в ту ли тему я пишу свой вопрос :) А состоит он вот в чем. Написал я...

могут ли быть одинаковые имена переменных в разных структурах
struct inMaterial { int number; string Date; string NumberDoc; int...

Необработанное исключение по адресу, нарушение прав доступа при записи по адресу
вот само задание: Авиарейсы (номер рейса, пункт назначения, время вылета, дата...

Можно ли в цикле for объявить две переменных разного типа?
Есть такой цикл for(сhar s='A',int i=0; s&lt;'Z'; s++,i++) {} Builder 6 выдает...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru