共享内存分段错误
segmentation fault on shared memory
我在使用共享内存时遇到了一些困难,当我试图查看变量中的内容时出现分段错误
printf("|%d|", mappa->map[i][j]->taxi);
但我写的时候不是
mappa->map[i][j]->taxi = rand() % 10;
我的第一个猜测是:好吧,我没有分配足够的 space。但是在“出租车”上写字时也不会失败吗?
PS 我需要在结构中包含“taxi”,因为稍后我将在该结构中包含更多元素
#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");
}
做的时候:
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);
是 'like' 做 mappa->map[i][j] = mappa
然后 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,或者更简单地使用每次调用时递增的 var shmget 等)
after that :#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <time.h>
#include <stdlib.h>
#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;
)隐藏指针是一个非常糟糕的主意,会产生很多问题并降低代码的可读性,我强烈建议您让 *
可见。
我在使用共享内存时遇到了一些困难,当我试图查看变量中的内容时出现分段错误
printf("|%d|", mappa->map[i][j]->taxi);
但我写的时候不是
mappa->map[i][j]->taxi = rand() % 10;
我的第一个猜测是:好吧,我没有分配足够的 space。但是在“出租车”上写字时也不会失败吗?
PS 我需要在结构中包含“taxi”,因为稍后我将在该结构中包含更多元素
#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");
}
做的时候:
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);
是 'like' 做 mappa->map[i][j] = mappa
然后 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,或者更简单地使用每次调用时递增的 var shmget 等)
after that :#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <time.h>
#include <stdlib.h>
#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;
)隐藏指针是一个非常糟糕的主意,会产生很多问题并降低代码的可读性,我强烈建议您让 *
可见。