[英]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 *memaddress
這int *memaddress
shmget的結果存儲為整數,這是不對的。 您需要檢查memaddress的所有相關用法是否正確。 您可以在gdb中進行檢查,查看shmget的結果,確保將其存儲在shared_mem [0]中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.