Несколько связанных указателей - PullRequest
1 голос
/ 20 марта 2019

Для домашней работы я должен построить следующий простой сценарий.

enter image description here

Моя попытка выглядит так:

#include <stdlib.h>

int main() {
  char* heap1P = malloc(sizeof(char**));
  char* heap2P = malloc(sizeof(char*));
  char* heap3P = malloc(sizeof(char));

  *heap3P = 'X';
  *heap2P = heap3P;
  *heap1P = heap2P;

  char*** stackP = heap1P;

  puts("stack                           | heap ");
  printf("%p [%p] | %p [%p] => %p [%p] => %c [%p] \n", stackP, &stackP, *heap1P, heap1P, *heap2P, heap2P, *heap3P, heap3P);

  return EXIT_SUCCESS;
}

Сначала я выделяю место в памяти, а затем устанавливаю значения.Выходные данные имеют вид (формат: значение [адрес]):

stack                           | heap 
0x55a1e184f260 [0x7fff05e55c08] | 0xffffff80 [0x55a1e184f260] => 0xffffffa0 [0x55a1e184f280] => X [0x55a1e184f2a0] 

Как вы можете видеть, значение стека содержит адрес первого значения кучи.Но значения кучи не верны.Они не содержат адрес следующего значения кучи.

Почему значения кучи не содержат заданные адреса?

Ответы [ 2 ]

5 голосов
/ 20 марта 2019

Проблема только в том, что вы объявили различный указатель как char *.Это может выглядеть неважно, потому что в общих реализациях все указатели имеют одинаковое представление.Но это становится необходимым, как только вы разыграете их!

Давайте посмотрим на следующие утверждения:

*heap3P = 'X';
*heap2P = heap3P;

Первое правильное: heap3P - это char * и *heap3P назначен char, здесь все хорошо.

Второй ужасен.Поскольку heap2P является char *, heap3P, если преобразовано в целое число и обрезано в char!Короче говоря: вы сохраняете только один байт из указателя ... И если вы внимательно посмотрите на значения, вы увидите, что различные heapx действительно являются однобайтовыми значениями ...

Исправлениетривиально:

char*** heap1P = malloc(sizeof(char**));
char** heap2P = malloc(sizeof(char*));
char* heap3P = malloc(sizeof(char));

и код компилируется без предупреждения и работает как положено!

0 голосов
/ 20 марта 2019

Я думаю, вы хотели бы что-то вроде:

typedef struct heap {
    char val;
    struct heap *next;
} heap_t;

int main()
{
    // allocate first
    heap_t *head = malloc(sizeof(heap_t));
    head->val = 'A';
    // allocate second node
    head->next = malloc(sizeof(heap_t));
    head->next->val = 'B';

    head->next->next = malloc(sizeof(heap_t));
    head->next->next->val = 'X';

    heap_t *tmp = head;
    for (int i = 0; i < 3; i++, tmp = tmp->next) {
        printf("[%p, %c]\n", tmp, tmp->val);
    }
}

Обратите внимание, что это быстрый черновик, и вы, конечно, должны создавать новые узлы внутри функции, а не вручную, как я это сделал здесь,Не забудьте потом освободить память.

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