Указатели, 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;
Другие вопросы по тегам