繁体   English   中英

Linux共享内存段错误

[英]Linux shared memory segfault

我一直很难在示例C程序(RHEL 6)中获得可用的共享内存区域。 它应该是非常基本的,所以我不确定我在做什么错,但是当我分配内存区域时,它最初似乎是可访问的。 但是,当我从初始化函数返回时,无法再访问该存储区域,并且在尝试访问该存储区域时出现段错误。

我已经尝试通过GDB运行它,而我所看到的只是在我尝试执行此memcpy的那一行上出现的段错误:

memcpy(ptr, &x, sizeof(x));

由于某种原因,我可能看不到它,这可能是很小的事情! 谢谢。

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <errno.h>


void* shared_mem[2];

int init(int *memAddress);

int main() {

  if(init((int*)&shared_mem[0]) < 0) {
    printf("Error initializing, exiting\n");
    exit(1);
  }

  int *ptr=shared_mem[0];

  int x=278;
  memcpy(ptr, &x, sizeof(x));
  printf("data written to memAddress: %d\n", shared_mem[0]);

}

// Initialize shared memory region and insert test data
int init(int *memAddress) {
    key_t key = 234324;
    int size = sizeof(int);
    static const unsigned int flags = S_IRUSR | S_IWUSR | S_IRGRP |
                                       S_IWGRP | S_IROTH | S_IWOTH | IPC_CREAT;
    int id = shmget(key, size, flags);
    if (id < 0)
    {
        return(-3);
    }
    *memAddress = shmat(id,0,0);
    if ((int)memAddress == -1)
    {
        return(-4);
    }

    int z=123;
    memcpy(memAddress, &z, sizeof(z));
    printf("data written to memAddress: %d\n", memAddress[0]);
    return(0);
}

这是完全错误的,它从以下几行开始:

int init(int *memAddress)

您将指向shared_mem的指针传递给函数“ init”。 因此, memAddress将指向8或16字节(取决于CPU类型)数组shared_mem

*memAddress = shmat(id,0,0);

如果sizeof(void *) == sizeof(int)可以,但是您必须进行其他指针转换。 shared_mem[0]将包含一个指向内存的指针,该指针被强制转换为int

如果sizeof(void *) != sizeof(int)您将在这里遇到问题。

(int)memAddress == -1

这在任何情况下均不起作用:

(int)memAddress是数组shared_mem的地址,而不是shmat返回的值。

memcpy(memAddress, &z, sizeof(z));

这会将值123写入shared_mem[0] 因此,以下说明:

memcpy(ptr, &x, sizeof(x));

...将等于:

memcpy((void *)123, &x, sizeof(x));

...这将导致错误。

正确的函数如下所示:

int init(void **memAddress) {     // void **
    ...
    *memAddress = shmat(id,0,0);  // This was correct!
    if ((int)(*memAddress) == -1) // Note the "*"
        ...
    memcpy(*memAddress, &z, sizeof(z)); // Note the "*"
}

您的init函数未使用分配的内存地址修改shared_mem-init()的参数需要声明为int **memaddress ,例如,查看您的行*memaddress=shmget(...) ,其参数定义为int *memaddressint *memaddress shmget的结果存储为整数,这是不对的。 您需要检查memaddress的所有相关用法是否正确。 您可以在gdb中进行检查,查看shmget的结果,确保将其存储在shared_mem [0]中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM