Указатели, struct и malloc()
Я сделал эту простую программу для тестирования struct
, указатели и malloc()
программирования на C:
#include <stdlib.h>
#include <stdio.h>
typedef struct l {
unsigned val;
struct l * next;
} list;
typedef struct cont {
list ** mat;
unsigned riga;
} container;
int main(){
container * c = (container *)malloc(sizeof(container));
c->riga = 3;
c->mat = (list**)malloc(sizeof(list*)*3);
for(int i = 0; i<3 ;i++){
c->mat[i] = NULL;
}
c->mat[0] = (list *)malloc(sizeof(list));
c->mat[0]-> val = 4;
c->mat[0]-> next = NULL;
printf("val row 0: %d\n", c->mat[0]->val);
/*************************/
list * ca = c->mat[1];
ca = (list *)malloc(sizeof(list));
ca->val = 2;
ca->next = NULL;
printf("val row 1: %d\n", c->mat[1]->val);
return 0;
}
Проблема в том, что я получаю segfault на 2-й printf()
... не должен c->mat[1]
а также ca
быть эквивалентным?
Разве они не должны указывать на одну и ту же выделенную память?
Первоначально c->mat[1]
является NULL
так это ca = c->mat[1] = NULL
, после ca= malloc()
это указывает на что-то еще... как насчет c->mat[i]
? А что если я сделаю наоборот?
3 ответа
ca
является копией c->mat[1]
поэтому, когда вы позже измените ca
чтобы указать на список malloc-ed, это не копия c->mat[1]
больше и особенно, если вы измените ca
Вы также не модифицируете c->mat[1]
,
Если ca
были не указателем, а int
Вы не ожидаете этого, или вы предполагаете, что a было 2 в следующем примере?
int a = 3;
int ca = a;
ca = 2;
Конечно, если ca
является копией c->mat[1]
и вы меняете *c
тогда ты тоже меняешь *(c->mat[1])
,
list * ca = c->mat[1];
установите CA в NULL
ca = (list *)malloc(sizeof(list));
установите ca, чтобы указать на новую память, заданную из malloc, но c->mat[1] по-прежнему указывают на NULL.
у вас может быть указатель на указатель c->mat[1]:
list ** ca = &c->mat[1];
(*ca) = malloc(sizeof(list));
(*ca)->val = 2;
(*ca)->next = NULL;
и не забудьте использовать free().
Код для c->mat[0]
правильно, и может быть использовано для c->mat[1]
,
Или вы исправите код c->mat[1]
код, присваивая результаты malloc
в c->mat[1]
а затем скопируйте указатель на ca
c->mat[1] = malloc(sizeof(list));
list *ca = c->mat[1];
ca->val = 2;
ca->next = NULL;
Другое решение состоит в том, чтобы скопировать ca
в c->mat[1]
в конце
list *ca = malloc(sizeof(list));
ca->val = 2;
ca->next = NULL;
c->mat[1] = ca;