gpt4 book ai didi

c++ - 在 C++ 中写入 IPC SHM 时无法读取完整的字符串

转载 作者:行者123 更新时间:2023-11-28 01:17:52 28 4
gpt4 key购买 nike

我正在尝试构建一个简单的界面以在 C++ 中使用 shm ipc。为此,我编写了以下代码:

sharedmem.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 构建。 && 制作

在这个例子中,我写了“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);
}

stringstream ss 在你的函数中没有任何功能用途,除了添加一个 bug。我建议您试试这个:

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 引用传递的,这是为了避免复制它们(以及与那些不需要的内存分配相关的潜在错误)

关于c++ - 在 C++ 中写入 IPC SHM 时无法读取完整的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58049785/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com