c - 如何检查共享内存是否为空?

标签 c null shared-memory coredump

我有一个使用共享内存的项目,我每次都有一个 while 循环读取它,因此我想检查它是否为空。 打开共享内存的代码使用:

key_t key;
int shmid;
if ((key = ftok("ex31.c", 'k')) == -1){
    perror("ftok");
    exit(1);}
if ((shmid = shmget(key, 3, FLAGS)) == -1) {
            perror("shmget");
            exit(1);}
char* shmaddr;
if( shmaddr=shmat(shmid,0,0) == (char*)-1){
    printf("error in attaching to the shared memory\n");
    exit(0);}
if(shmaddr==NULL) /// THROWS EXCEPTION!!

它给我错误:

 segmentation fault (core dumped)

..帮助?

最佳答案

我建议你快速浏览一下这个完整的程序,看看当你运行它两次时会发生什么,第一次使用参数-1,然后再次使用42 的参数:

#include <stdio.h>
int main (int argc, char *argv[]) {
    int i;
    if (i = atoi (argv[1]) == -1)
        printf ("   WAS negative one: %d\n", i);
    else
        printf ("   was NOT negative one: %d\n", i);
    return 0;
}

实录如下:

pax> ./testprog -1
   WAS negative one: 0
pax> ./testprog 42
   was NOT negative one: 1

你可以在那里看到,即使它正确地检测到 atoi 值,但在比较之后 i 似乎没有正确设置。

如果您查看您的代码,您已经知道(或者很快知道,一旦您读完这个答案)如何解决这个问题。将您的错误行与其他一行进行比较(都稍微重新格式化以使其明显):

if  ((shmid   = shmget (key, 3, FLAGS)) == -1       ) {
if   (shmaddr = shmat  (shmid, 0, 0  )  == (char*)-1) {
//  ^                                 ^
//   \_______extra parentheses_______/

第二行没有按预期工作的原因是 === 具有更高的优先级。这意味着第一行做你想做的,但第二行是有效的:

if (shmaddr = (shmat (shmid, 0, 0) == (char*)-1) ) {
//  \          \________higher________________/ /
//   \____________________lower________________/

如您所见,该优先规则意味着首先对表达式 shmat (shmid, 0, 0) == (char*)-1 求值,然后计算结果 (1 为 true 或 0 为 false)分配给 shmaddr。这两个值非常都不太可能是有效的内存地址,因此当您尝试取消引用它时几乎肯定会导致崩溃(a)

您需要的行应该与其他两行的格式相匹配,并在赋值周围加上括号以确保它先完成:

if ((shmaddr = shmat (shmid, 0, 0)) == (char*)-1)) {
// ^                              ^
//  \__________add these_________/

(a) 1 被分配的情况与您的情况无关,因为这意味着 if 条件评估为真,您的程序将导出。因此,尝试取消引用 shmaddr 的代码的唯一 路径会将其设置为 0。

关于c - 如何检查共享内存是否为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37146135/

相关文章:

iphone - matchTemplate opencv 无法正常工作,如 opencv 文档中所示

c++ - 无法从 C 无错误地调用 C++ 代码

如果未进行连接,则 Mysql 选择列为 null

c# - 该字段永远不会分配给并且始终具有其默认值 null

使用 execlp() 调用可执行文件

c++ - 从 boost 共享内存转储数据的最佳方法

c - 内存中的代码向哪个方向执行?

.net - null 在 .NET 中如何表示

linux -/tmp vs./dev/shm 用于 Linux 上的临时文件存储?

c - 如何在汇编中访问 C 预处理器常量?