gpt4 book ai didi

C++/Qt memcpy 与 QSharedMemory 崩溃

转载 作者:行者123 更新时间:2023-11-30 03:32:38 24 4
gpt4 key购买 nike

我有一个简单的函数,它使用 Qt (5.5.1) QSharedMemory 类将字符串(uri 链接或文件路径)发送到已运行的应用程序实例。

它似乎在大多数时候都能正常工作,但我从用户那里捕获了一个崩溃日志,它在 memcpy 上崩溃了。该函数如下所示:

void WindowsApp::SendData( char* uri )
{
int size = 1024;
if (!m_SharedMemory.create(size)) {
qDebug() << "Unable to create shared memory segment." << m_SharedMemory.error();
return;
}
m_SharedMemory.lock();
char *to = (char*)m_SharedMemory.data();
const char *from = uri;
memcpy(to, from, qMin(m_SharedMemory.size(), size));
m_SharedMemory.unlock();
QThread::sleep(10);
}

m_SharedMemory 是类的 QSharedMemory 类型静态成员。

从日志中,我看到我尝试发送的字符串是一个简单的文件路径,没有特殊字符,而且不太长,只有 150 个字符。

有什么问题,但我无法用类似的参数重现它?

最佳答案

代码具有未定义的行为,因为您正在阅读源字符串的末尾:您总是读取 1024 个字节,即使源字符串是例如5 个字节长。正如您所指出的,UB 不能保证崩溃。通常它会在重要的演示期间崩溃。如果字符串太长而无法放入内存段,您也不能确保该字符串将以零终止,因此如果接收器试图将字符串视为以零终止,则它可能会崩溃。

这些问题很可能是由于缺乏设计造成的。内存段的内容暗示了发送者和接收者之间的契约。双方必须就某事达成一致。让我们定义契约:

  1. 共享内存段的内容是一个以 null 结尾的 C 字符串。

    这就是所谓的不变量:无论发生什么,它始终为真。这使读者能够安全地使用 C 字符串 API,而无需首先检查是否存在空终止。

  2. 太长的 uri 被替换为空字符串。

    这对作者来说是一个后置条件:它意味着写作将在内存中放置一个完整的 URI,或者一个空字符串。

修复方法如下:

bool WindowsApp::WriteShared(const char * src, int length) {
if (m_SharedMemory.lock()) {
auto const dst = static_cast<char*>(m_SharedMemory.data());
Q_ASSERT(dst);
memcpy(dst, src, length);
m_SharedMemory.unlock();
return true;
}
return false;
}

bool WindowsApp::SendData(const char* uri)
{
Q_ASSERT(uri);
if (!m_SharedMemory.create(1024)) {
qWarning() << "Unable to create shared memory segment." << m_SharedMemory.error();
return false;
}
int const uriLength = strlen(uri) + 1;
if (uriLength > m_SharedMemory.size()) {
qWarning() << "The uri is too long.";
if (! WriteShared("", 1))
qWarning() << "Can't clear the memory.";
return false;
}
if (! WriteShared(uri, uriLength)) {
qWarning() << "Can't lock the shared memory segment.";
return false;
}
QThread::sleep(10);
return true;
}

关于C++/Qt memcpy 与 QSharedMemory 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43391314/

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