从std :: string转换为const char *导致' Syscall param socketcall.sendto(msg)指向不可寻址的字节' valgrind中的错误

时间:2017-04-07 17:40:26

标签: c++ string http valgrind

使用 libmicrohttpd 库时,我在将string转换为const char *并使用MHD_create_response_from_buffer调用const char *cstring = "this is a page";时遇到了一个奇怪的错误。

这会导致网页响应严重错误,偶尔显示二进制数据,而且更少一点,使浏览器认为它是一个文件并下载它。

这真是奇怪的是,如果我发送一个常规的const char,就不会出现错误 string 只有当我从const char *转换为const char *cstring = page.c_str();时才会这样 ==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==

Valgrind输出:

std::string

发送数据的功能(在this page找到并且仅修改为使用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; } ):

{{1}}

2 个答案:

答案 0 :(得分:3)

您的参数std::string page是一个局部变量。此函数完成后,将释放其内存。

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

您应确保缓冲区保持活动状态,方法是以不同的方式分配缓冲区,或者阻止主要线程直到获得响应。

答案 1 :(得分:2)

我似乎已经自己解决了这个问题。对于提出不必要的问题感到抱歉。

通过将MHD_create_response_from_buffer上的第三个参数从MHD_RESPMEM_PERSISTENT更改为MHD_RESPMEM_MUST_COPY来解决问题

再次,抱歉。