Мутабельность указателя в си
Минимальный пример
#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.