使用C++的Linux共享内存:分段错误
我正在关注Linux编程接口手册(第1004-1005页)。使用C++的Linux共享内存:分段错误
我知道这本书使用C.但我想在C++中实现相同的行为。即:通过共享内存在进程之间共享结构。
#include <iostream>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
using namespace std;
struct my_pair {
int a;
int b;
};
int main()
{
key_t key = ftok("aaaaa", 1);
int shmid = shmget(key, sizeof(my_pair), IPC_CREAT);
my_pair *numbers;
numbers = shmat(shmid, NULL, 0);
cout << numbers->a;
return 0;
}
它给我这个错误:
shteste.cpp: In function 'int main()':
shteste.cpp:18: error: invalid conversion from 'void*' to 'my_pair*'
据我所知,C++更为严格。如果我将shmat返回给(my_pair *),它会编译但在执行期间给我分段错误。
是否有可能(如何)使用C/C++的Linux/C共享内存设施?
我与编译:G ++ 4.4.7:G ++ shteste.cpp -o shteste -std =的C++ 0x
谢谢...
编辑:继所有sugestions,这是现在代码:
int main()
{
key_t key;
if ((key = ftok("/home/alunos/scd/g11/aaaaa", 1)) == (key_t) -1) {
perror("IPC error: ftok"); exit(1);
}
int shmid = shmget(key , sizeof(my_pair), IPC_CREAT | 0640);
if (shmid == -1) {
perror("Could not get shared memory");
return EXIT_FAILURE;
}
my_pair *numbers;
void* mem = (my_pair*) shmat(shmid, NULL, 0);
if (mem == reinterpret_cast<void*>(-1)) {
perror("Could not get shared memory location");
return EXIT_FAILURE;
} else {
numbers = reinterpret_cast<my_pair*>(mem);
cout << numbers->a;
}
return EXIT_SUCCESS;
}
AAAAA内容:notacat
[[email protected] ~]$ ./shteste
Could not get shared memory: Permission denied
这可能是一个权限问题。您可以检查返回值shmget
和shmat
并使用perror
来打印这样的人类可读的错误消息。
#include <iostream>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
struct my_pair {
int a;
int b;
};
int main()
{
key_t key = ftok("aaaaa", 1);
int shmid = shmget(key, sizeof(my_pair), IPC_CREAT | 0777);
if (shmid == -1) {
perror("Could not get shared memory");
return EXIT_FAILURE;
}
my_pair *numbers;
void* mem = (my_pair*) shmat(shmid, NULL, 0);
if (mem == reinterpret_cast<void*>(-1)) {
perror("Could not get shared memory location");
return EXIT_FAILURE;
} else {
numbers = reinterpret_cast<my_pair*>(mem);
cout << numbers->a;
}
return EXIT_SUCCESS;
}
您绝对正确:“无法获取共享内存位置:权限被拒绝”。我应该问系统管理员,还是有我作为用户/开发人员可以做的事情? –
@VictorMarconi:不,你应该正确设置权限:-)看到我的答案! – Klaus
我想感谢大家。所有的答案都有帮助......问题是各有所长。 错误的权限。因此,我不能再使用相同的密钥(ftok)。非常感谢。 –
根据ftok
手册页:
The ftok() function uses the identity of the file named by the given
pathname (which must refer to an existing, accessible file).
使用现有文件的代码将工作。
或者您可以使用:
key = IPC_PRIVATE
这将足以在这个例子中,但不会真正的IPC工作。
我想感谢大家。所有的答案都有帮助......问题是各有所长。 错误的权限。因此,我不能再使用相同的密钥(ftok)。非常感谢。 –
你简单的忘记设置权限:
int shmid = shmget(key, sizeof(my_pair), IPC_CREAT | 0777);
正如我在我的评论已经提到的,失败的命令的结果可以用strace的看到。
64 5327 shmget(0xffffffff, 8, IPC_CREAT|000) = 11534358
65 5327 shmat(11534358, NULL, 0) = -1 EACCES (Permission denied)"
如果您的文件“aaaaa”存在,代码适用于我。
这是一个权限问题。
SYNOPSIS
#include <sys/shm.h> int shmget(key_t key, size_t size, int shmflg);
...
DESCRIPTION
...
- The low-order nine bits of shm_perm.mode are set to the low-order nine bits of shmflg.
您没有设置任何权限位。在您的通话shmflag的低位九个位都是零:
int shmid = shmget(key, sizeof(my_pair), IPC_CREAT);
您需要设置适当的权限,这样的事情:
int shmid = shmget(key, sizeof(my_pair), IPC_CREAT|0640);
您也将有可能使用ipcrm
删除当前的共享内存段,因为它将保持不正确的permssions。即使您更改了代码,您的shmget()
调用也会返回现有段的ID--由于缺少权限而无法附加的段。
首先,使用ipcs -a
列出共享内存段,然后使用ipcrm -m shmid
或ipcrm -M shmkey
删除具有不正确权限的段。
ipcs -a:没有列出共享内存段... –
我想感谢所有人。所有的答案都有帮助......问题是各有所长。 错误的权限。因此,我不能再使用相同的密钥(ftok)。非常感谢。 –
您确定错误是由您显示的代码产生的吗?如果你没有演员阵容,我会期待这个错误,就像'numbers = shmat(...)'。但演员应该照顾它。 –
你是对的......我复制了“固定”代码......我投下的代码(因此不会抱怨转换)但出现分段错误。 –
你应该检查'shmget'和'shmat'的返回值。 – bezet