C语言 Linux 共享内存段错误



我一直在示例 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, exitingn");
exit(1);
}
int *ptr=shared_mem[0];
int x=278;
memcpy(ptr, &x, sizeof(x));
printf("data written to memAddress: %dn", 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: %dn", memAddress[0]);
return(0);
}

这里完全错误,它以以下行开头:

int init(int *memAddress)

您将指向函数"init"的指针传递给函数shared_mem。因此,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 *memaddress这是将 shmget 的结果存储为整数,这是不对的。您需要检查 memaddress 的所有相关用法是否正确。你可以在 gdb 中检查这一点,查看 shmget 的结果,确保它存储在 shared_mem[0] 中。

最新更新