c++ - 从 std::string 转换为 const char* 导致 valgrind 出现 'Syscall param socketcall.sendto(msg) points to unaddressable byte(s)' 错误

标签 c++ string http valgrind

在使用 libmicrohttpd 库时,我在将 string 转换为 const char * 并调用 MHD_create_response_from_buffer 时遇到了一个奇怪的错误 和它一起。

这会导致返回的网页响应格式严重错误,偶尔会显示二进制数据,并且在极少数情况下会导致浏览器认为它是一个文件并进行下载。

真正奇怪的是,如果我发送一个常规的 const char,错误不会出现,比如 const char *cstring = "这是一个页面"; 仅当我从 string 转换为 const char *const char *cstring = page.c_str();

Valgrind 输出:

==11105== Thread 2:
==11105== Syscall param socketcall.sendto(msg) points to unaddressable byte(s)
==11105==    at 0x617464B: send (send.c:31)
==11105==    by 0x565986F: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0)
==11105==    by 0x565737D: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0)
==11105==    by 0x565DA3C: MHD_run_from_select (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0)
==11105==    by 0x565DC8A: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0)
==11105==    by 0x565DDA1: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0)
==11105==    by 0x876B0A3: start_thread (pthread_create.c:309)
==11105==    by 0x617362C: clone (clone.S:111)
==11105==  Address 0xe499448 is 24 bytes inside a block of size 56 free'd
==11105==    at 0x4C2A360: operator delete(void*) (vg_replace_malloc.c:507)
==11105==    by 0x401CA5: http_connect(void*, MHD_Connection*, char const*, char const*, char const*, char const*, unsigned long*, void**) (in /home/shpoople/projects/http/main)
==11105==    by 0x5656F70: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0)
==11105==    by 0x5658427: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0)
==11105==    by 0x565D988: MHD_run_from_select (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0)
==11105==    by 0x565DC8A: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0)
==11105==    by 0x565DDA1: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0)
==11105==    by 0x876B0A3: start_thread (pthread_create.c:309)
==11105==    by 0x617362C: clone (clone.S:111)
==11105==

以及用于发送数据的函数(位于 this page 并且仅修改为使用 std::string):

static int send_page (struct MHD_Connection *connection, std::string page) {
    int ret;
    struct MHD_Response *response;
    const char* cstring = page.c_str();

    response = MHD_create_response_from_buffer (strlen (cstring), (void *) cstring, MHD_RESPMEM_PERSISTENT);

    if (!response) {
        return MHD_NO;
    }

    ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
    MHD_destroy_response (response);

    return ret;
}

最佳答案

您的参数 std::string page 是一个局部变量。当这个函数完成时,它的内存被释放。

另一方面,函数 MHD_run_from_select 和相关函数显然在单独的线程上运行。当该线程尝试访问缓冲区时,std::string page 的内存已被释放。

您应该通过以不同方式分配缓冲区或阻塞主线程直到获得响应来确保缓冲区保持事件状态。

关于c++ - 从 std::string 转换为 const char* 导致 valgrind 出现 'Syscall param socketcall.sendto(msg) points to unaddressable byte(s)' 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43284133/

相关文章:

c++ - 使用 Windows C++ LockFIle() 锁定文件然后从中获取流?

delphi - 分配给 TStringList 时字符串丢失数据

http - 如何取消在 Flutter 中使用 http.MultipartRequest() 发送的正在进行的文件上传?

html - 资源预加载作为 HTTP header 或作为响应中的标记之间的权衡是什么?

c++ - 可以在 C/C++ include 指令中使用环境变量吗?

c++ - 如何在Qt中强制绘画?

C++ 如何比较类

Java - 从混合了 UTF-8 和非 UTF-8 字符的字符串中准确计算 60 个字符

java - 如何将支票转换为包含小数位的文字

http - 如何测试 mochiweb 应用程序?