У меня возникли трудности с общей памятью, я получаю ошибку сегментации, когда пытаюсь посмотреть, что находится внутри переменной

printf("|%d|", mappa->map[i][j]->taxi);

но не тогда, когда я пишу на нем

mappa->map[i][j]->taxi = rand() % 10;

Первой моей догадкой было: хорошо, я не выделяю достаточно места. Но разве при попытке написать на "такси" также не произойдет сбой?

PS Мне нужно иметь "такси" внутри структуры, потому что позже у меня будет больше элементов в этой структуре

#define KEY 6666

typedef struct cell {
    int taxi;
} cell;
typedef cell *cella;

typedef struct city
{
    cella map[5][5];
} city;

typedef city *citta;


int main(int argc, char const *argv[])
{
    citta mappa;
    cella single_cell;
    int id_mappa;
    int id_cell;
    id_mappa = shmget(KEY, sizeof(*mappa), IPC_CREAT | 0666);
    mappa = shmat(id_mappa, NULL, 0);
    srand(time(NULL));
    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            printf("ciao\n");
            id_cell = shmget(KEY + i + j, sizeof(*single_cell), IPC_CREAT | 0666);
            mappa->map[i][j] = shmat(id_cell, NULL, 0);
            mappa->map[i][j]->taxi = rand() % 10;
            printf("|%d|", mappa->map[i][j]->taxi);
        }
        printf("\n");
    }
    printf("-------------\n");
}

Ответы (1)

когда делать :

id_cell = shmget(KEY + i + j, sizeof(*single_cell), IPC_CREAT | 0666);

Вы используете несколько раз один и тот же ключ, в первом цикле i и j равны 0, поэтому используемый ключ KEY + 0 + 0, поскольку KEY уже использовался для mappa, а затем в первом цикле mappa->map[i][j] = shmat(id_cell, NULL, 0); это "как" сделать mappa->map[i][j] = mappa then mappa->map[i][j]->taxi = rand() % 10; не имеет ожидаемого поведения для установки mappa->map[i][j] со случайным значением, которое не является корректным указателем, когда вы пытаетесь разыменовать его в следующей строке, чтобы вывести значение mappa->map[i][j]->taxi.

Делайте, например, так :

id_cell = shmget(KEY + i + j*10 + 1, sizeof(*single_cell), IPC_CREAT | 0666);

чтобы каждый раз иметь разный ключ (конечно, можно просто умножить j на 5, или более просто использовать переменную, которая увеличивается каждый раз, когда вы вызываете shmget и т.д.)

after that :#include 
#include 
#include 
#include 
#include 

#define KEY 6666

typedef struct cell {
    int taxi;
} cell;
typedef cell *cella;

typedef struct city
{
    cella map[5][5];
} city;

typedef city *citta;


int main(int argc, char const *argv[])
{
    citta mappa;
    cella single_cell;
    int id_mappa;
    int id_cell;
    id_mappa = shmget(KEY, sizeof(*mappa), IPC_CREAT | 0666);
    mappa = shmat(id_mappa, NULL, 0);
    srand(time(NULL));
    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 5; j++)
        {
            printf("ciao\n");
            id_cell = shmget(KEY + i + j*10 + 1, sizeof(*single_cell), IPC_CREAT | 0666);
            mappa->map[i][j] = shmat(id_cell, NULL, 0);
            mappa->map[i][j]->taxi = rand() % 10;
            printf("|%d|", mappa->map[i][j]->taxi);
        }
        printf("\n");
    }
    printf("-------------\n");
}

Компиляция и выполнение :

pi@raspberrypi:/tmp $ gcc -Wall c.c
pi@raspberrypi:/tmp $ ./a.out
ciao
|3|ciao
|5|ciao
|0|ciao
|9|ciao
|5|
ciao
|0|ciao
|7|ciao
|8|ciao
|3|ciao
|1|
ciao
|3|ciao
|2|ciao
|7|ciao
|0|ciao
|1|
ciao
|4|ciao
|4|ciao
|5|ciao
|2|ciao
|0|
ciao
|8|ciao
|2|ciao
|6|ciao
|4|ciao
|1|
-------------
pi@raspberrypi:/tmp $ 

и

pi@raspberrypi:/tmp $ valgrind ./a.out
==8741== Memcheck, a memory error detector
==8741== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8741== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==8741== Command: ./a.out
==8741== 
ciao
|3|ciao
|2|ciao
|7|ciao
|6|ciao
|3|
ciao
|5|ciao
|8|ciao
|1|ciao
|9|ciao
|2|
ciao
|3|ciao
|7|ciao
|9|ciao
|0|ciao
|3|
ciao
|9|ciao
|1|ciao
|3|ciao
|9|ciao
|5|
ciao
|8|ciao
|6|ciao
|1|ciao
|3|ciao
|1|
-------------
==8741== 
==8741== HEAP SUMMARY:
==8741==     in use at exit: 0 bytes in 0 blocks
==8741==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==8741== 
==8741== All heap blocks were freed -- no leaks are possible
==8741== 
==8741== For lists of detected and suppressed errors, rerun with: -s
==8741== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
pi@raspberrypi:/tmp $ 

Кроме того, скрывать указатели через typedef (пример typedef cell *cella;) - очень плохая идея, создающая много проблем и делающая ваш код менее читабельным, я настоятельно рекомендую вам сделать * видимым.

2022 WebDevInsider