Мутабельность указателя в си

Минимальный пример

#include <stdio.h>
#include <stdlib.h>

typedef struct map_s {
   struct map_s * next;
} map_t;

struct data {
  map_t * map;
};

void insert(map_t * map) {
  map_t * new = malloc(sizeof(map_t));
  new->next = map;
  fprintf (stderr,"\n%p", new);
  map = new;
}

int main() {
 struct data d;
 d.map = NULL;
 fprintf (stderr,"\n%p", d.map);
 insert(d.map);
 fprintf (stderr,"\n%p", d.map);
 return 0;
}

Я хочу чтоб d.map было равно new после выполнения функции.


Ответы (1 шт):

Автор решения: AlexGlebe

Пример как пользоваться указателем на указатели и с добавлением обработки исключений как положено.

// gcc -Wall -Wextra -Wpedantic -std=c11 ssyl.c -o ssyl
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

typedef struct map_s {
   struct map_s * next;
} map_t;

struct data {
  map_t * map;
};

jmp_buf * exceptionp ;

void insert ( map_t * * const mapl ) {
  map_t * new = malloc(sizeof(map_t));
  if ( new == NULL )
    longjmp ( * exceptionp , 1 ) ;
  new->next = * mapl ;
  fprintf (stderr,"\ninsert:%p", (void*)new);
  * mapl = new ;
}

int main() {
  jmp_buf jbmain ;
  exceptionp = & jbmain ;
  if ( setjmp ( * exceptionp ) ) {
    fputs("OutOfMemory\n",stderr);
    exit(1); }
 struct data d;
 d.map = NULL;
 fprintf (stderr,"\n0.main:%p", (void*)d.map);
 insert(&d.map);
 fprintf (stderr,"\n1.main:%p", (void*)d.map);
 return 0;
}

Чтобы переменную d.map можно было поменять с помощью другой функции нужно передать указатель на эту переменную, так-как аргументы во все функции передаются копированием. Переменная аргумент map_t * * const mapl имеет значение только внутри функции insert. Она указывает на удалённый указатель типа map_t *. Взять и поменять значение удалённого указателя можно с помощью записи * mapl.

→ Ссылка