在 c++ 中写入 IPC SHM 时无法读取完整的字符串
Can't read complete string when writing into IPC SHM in c++
我正在尝试构建一个简单的接口来在c ++中使用shm ipc。为此,我编写了以下代码:
共享记忆.h:
#pragma once
#include <iostream>
#include <sstream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
using namespace std;
namespace IPC
{
void Send(const string filename, std::string msg,int size=1024 )
{
key_t key = ftok(filename.c_str(),65);
std::stringstream ss;
ss << msg.c_str();
int shmid = shmget(key,size,0666|IPC_CREAT);
char *str = (char*) shmat(shmid,(void*)0,0);
ss >> str;
shmdt(str);
}
string Receive(const string filename, int size=1024 )
{
key_t key = ftok(filename.c_str(),65);
int shmid = shmget(key,size,0666|IPC_CREAT);
char *str = (char*) shmat(shmid,(void*)0,0);
string ret(str);
shmdt(str);
shmctl(shmid,IPC_RMID,NULL);
return ret;
}
};
在外面,我像这样使用它:
发件人.cpp
#include "sharedmem.h"
int main()
{
IPC::Send("fila1", "hello ipc");
return 0;
}
接收器.cpp
#include "sharedmem.h"
int main()
{
std::string ret = IPC::Receive("fila1");
cout << "Recebi na fila: " << ret;
return 0;
}
CMakeLists.txt:
set (CMAKE_CXX_STANDARD 17)
add_executable(sender sender.cpp)
add_executable(receiver receiver.cpp)
并用cmake . && make
建造
在这个例子中,我写"hello ipc",但另一个进程只读"hello"。这里可能出了什么问题?提前谢谢。
在发送函数中:
void Send(const string filename, std::string msg,int size=1024 )
{
key_t key = ftok(filename.c_str(),65);
std::stringstream ss;
ss << msg.c_str();
int shmid = shmget(key,size,0666|IPC_CREAT); // this call could fail, what happens next is
// a likely a segmentation error.
// ... or worse.
char *str = (char*) shmat(shmid,(void*)0,0);
ss >> str; // <-- error is here. You extract from ss until the first whitespace character.
// what happens if input string is larger than the size of the allocated block?
shmdt(str);
}
字符串流 ss 在您的函数中没有任何功能用途,除了添加错误。 我建议你试试这个:
int Send(const string& filename, const std::string& msg) noexcept // if you have no return value,
// you should throw on error,
// let's avoid that
{
key_t key = ftok(filename.c_str(), 65); // you should maybe consider using a named constant
// for your project ID
if (key == -1)
return errno;
int shmid = shmget(key, msg.length() + 1, 0666 | IPC_CREAT); // allocate enough memory for the
// message, plus its NULL terminator
if (shmid == -1)
return errno;
void *shared_mem = shmat(shmid, nullptr, 0);
if (shared_mem == (void*)-1)
{
// the systeml failed to lock the allocated memory.
// do some cleanup by de-allocating the shared memory block.
int ret = errno; // keep original error for return.
shmctl(shmid , IPC_RMID, nullptr);
return ret;
}
// copy message string with its NULL terminator to shared memory
memcpy(shared_mem, msg.c_str(), msg.length() + 1); // using length() + 1 is ok here, result of
// c_str() always has a NULL terminator.
shmdt(shared_mem);
return 0;
}
您的接收函数也缺乏错误检查。 这应该与 Send(( 函数非常相似。
请注意,字符串是通过 const 引用传递的,这是为了避免复制它们(以及与那些不需要的内存分配相关的潜在错误(
相关文章:
- 如何使用Luacneneneba API正确读取字符串和表参数
- 如何从二进制文件中读取字符串
- 如何在 c++ 中使用 getline 从文件中读取字符串?
- 读取字符串文本输入以创建 2D 矢量
- 罗马数字到阿拉伯语 (vinculum) - 读取字符串中的字符
- C++:从文件中读取字符串和整数,并获得最大数字
- C++,从文件中读取字符串,分段错误
- 如果语句错误地读取字符串,则始终在第一个条件返回
- 如何从内存中读取字符串?
- 如何创建一个C++程序来读取字符串数组中的信息,然后将其排序到类中?
- 我需要C++读取字符串数组中每个单词的第一个字母
- 读取字符串C++的字符时出错
- 读取字符串直到标志 (C++)
- 读取字符串字符时出错 - 对于数组中的字符串值
- C++输入文件流无法从文件中读取字符串
- 读取字符串字符时出错
- 如何读取<字符串,矢量<对<int,字符串的映射>>>
- 如何使此函数使用 getline 读取字符串并使用 int 执行相同的行为?
- C++ 使用 Strtok 读取字符串字符时出错
- 使用 getline 读取字符串,但每行中都有换行符