Запись указателя в память. С++

Тема в разделе "WASM.BEGINNERS", создана пользователем CrawlUp, 19 июл 2018.

  1. CrawlUp

    CrawlUp Member

    Публикаций:
    0
    Регистрация:
    1 фев 2018
    Сообщения:
    90
    Начал изучать С++ и не могу разобраться с простыми операциями. Странно что его рекомендуют как первый язык, ассемблер на мой взгляд значительно проще.
    Как записать значение адреса массива в выделенную память.
    int *pMassive = new int [1];
    int **pAdressMassive = &pMassive;

    pMassive[0] = pAddressMassive - компилятор выдает ошибку
    int A = pAddressMassive - также ошибка, этот адрес вообще записать в переменную нельзя
    *pMassive = pAddressMassive - также ошибка

    каким же чудесным образом я могу записать адрес массива хоть куда нибудь? И почему я не могу записать адрес в выделенную память?
    Операция которая на ассемблере не требует не каких усилий на С++ уже с ума меня свела.
    Или надо вывести этот адрес на консоль а потом как-то его прочитать с нее?
     
    Последнее редактирование: 19 июл 2018
  2. _edge

    _edge Well-Known Member

    Публикаций:
    1
    Регистрация:
    29 окт 2004
    Сообщения:
    631
    Адрес:
    Russia
    Сейчас в меня полетят помидоры, но плюсану за "операция которая на асм не требует никаких усилий, на Си с ума свела"

    Нужно насобачиться в этом. Применить 1-2 раз мало, нужно постоянно использовать указатели (по своему опыту, из головы без практики вылетает сразу же все, т.к., повторюсь, это ублюдочные конструкции).

    Код (C):
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. int main()
    4. {
    5.   int a, *b,c;
    6. // system("chcp 1251");
    7. // system("cls");
    8.   a = 134;
    9.  
    10.   b = &a;
    11.   // %x = вывод числа в шестнадцатеричной форме
    12.   printf("\n Значение переменной a равно %d = %x шестн.", a,a);
    13.   printf("\n Адрес переменной a равен %x шестн.", &a);
    14.   printf("\n Данные по адресу указателя b равны %d = %x шестн.", *b,*b);
    15.   printf("\n Значение указателя b равно %x шестн.", b);
    16.   printf("\n Адрес расположения указателя b равен %x шестн.", &b);
    17.  
    18. printf("\n\n");
    19.  
    20. c=*(&b);
    21.  
    22. printf("значение *(&b) = %d", c);
    23.  
    24.  
    25.   getchar();
    26.   return 0;
    27. }
    Также, Гугл. И еще можно рекомендовать в отладчике подсматривать, как оно скомпилировалось, то есть получили ли мы то, что хотели.
     
  3. zerodawn

    zerodawn Member

    Публикаций:
    0
    Регистрация:
    16 янв 2018
    Сообщения:
    94
    Это не адрес массива, то что вы записываете - адрес ячейки памяти, в которой хранится адрес массива.

    pMassive - переменная, в которой находится адрес массива, то есть это и есть указатель на массив
    pAddressMassive = &pMassive - адрес той самой переменной.

    то есть, адрес массива будет не pAddressMassive, а *pAddressMassive ( значение, которое хранится в переменной, на которую указывает pAddressMassive ).

    Да, это <цензура>

    А проблема в том, что вы не можете записать адрес указателя (int*) на массив (int*) в массив типа int, так как int** != int. То же самое с указателем на массив просто.

    тут два варианта

    I. Type-cast. не совсем верный код, т.к работать он будет только на x86
    Код (C):
    1. pMassive[0] = (int)pAddressMassive;
    sizeof(int) == 4
    sizeof(int*) == 4 // x86
    sizeof(int*) == 8 // x64 - не стоит забывать

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

    II. выделение массива указателей, что является более верным для этой задачи:
    Код (C):
    1.  
    2. int **pMassive = new int*[1];
    3. ...
    4. pMassive[0] = (int*)pAddressMassive; // оба валидные варианты
    5. *pMassive = (int*)pAddressMassive;
    6.  
     
    Последнее редактирование: 19 июл 2018
    CrawlUp нравится это.
  4. CrawlUp

    CrawlUp Member

    Публикаций:
    0
    Регистрация:
    1 фев 2018
    Сообщения:
    90
    Спасибо за ответы, первый ответ от _edge увы к результату не привел, возможно потому что этот синтаксис к С++ не подходит, а работает только для С. А вот от zerodawn именно то что нужно.
     
  5. f1redArk

    f1redArk Member

    Публикаций:
    0
    Регистрация:
    10 июл 2008
    Сообщения:
    34
    1) В II явный каст не нужен, там и так типы совпадают. И если уж так хотите каст, используйте плюсовый static_cast, а не сишное приведение типов
    2) Как правильно заметили выше, хранение указателя в инте - прямой путь отстрелить себе пару ног, если уж так хочется по каким то причинам засунуть указатель в целочисленную переменную, используйте uintptr_t, который для этих целей и существует.