c - 线程双释放中的卷曲请求
问题描述
char*
当我运行 N 个线程并且在每个线程中我使用 curl 读取响应来动态分配请求时,我遇到了问题。有时当我免费响应时我有错误double free or corruption (fasttop)
。下面的代码:
static void* crawler_threadHandler(void* _arg)
{
size_t thisId = (size_t)_arg;
crawler_thread* thisThread = &crawler.threads[thisId];
CURL *curl = curl_easy_init();
if (crawler.prepareRequestCommon != NULL)
{
crawler.prepareRequestCommon(curl);
}
while(thisThread->stopRequest == false)
{
crawler_runRequest(curl);
sleep(1);
}
curl_easy_cleanup(curl);
thisThread->isRunning = false;
return NULL;
}
static void crawler_runRequest(CURL* curl)
{
CURLcode res;
struct curl_slist* headers = NULL;
char* response = (char*) malloc(1);
if (crawler.prepareRequestEach != NULL)
{
crawler.prepareRequestEach(curl, headers);
}
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, crawler_reponseWriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*) response);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl);
curl_slist_free_all(headers);
if(res != CURLE_OK)
{
fprintf(
stderr,
"curl_easy_perform() failed: %s\n",
curl_easy_strerror(res)
);
}
else
{
if (crawler.parseResponse != NULL)
{
crawler.parseResponse(response);
}
}
if (response != NULL)
{
free(response); //Here is crash
}
}
static size_t crawler_reponseWriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
userp = realloc(userp, realsize + 1);
if (userp == NULL)
{
fprintf(
stderr,
"No space left in head for allocate response, bytes: %zu\n",
realsize
);
realsize = 0;
}
else
{
char terminateNull = '\0';
memcpy(userp, contents, realsize);
memcpy(userp + realsize, &terminateNull, 1);
}
return realsize;
}
函数crawler_threadHandler
是 pthread 处理程序调用
errno = pthread_create(&thread.pthread, NULL, crawler_threadHandler, (void*) i);
我的意思是有时崩溃:当我运行 3 个线程时,崩溃发生 1 或 2 次。
请帮助我不知道哪里是错误。
编辑:更改后工作:
//crawler_runRequest
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*) &response);
...
//crawler_reponseWriteCallback
void** responsePtr = userp;
*responsePtr = realloc(*responsePtr, realsize + 1);
...
memcpy(*responsePtr, contents, realsize);
memcpy(*responsePtr + realsize, &terminateNull, 1);
解决方案
推荐阅读
- versioning - 语义版本控制 2 零用例
- c# - 有没有人可以通过一个语句将多个孩子添加到 Xamarin 网格?
- java - 如果 JSON 包含属性的特定值,则解析它
- javascript - 如何使用纯 JS 将数据从 json 文件加载到单选按钮?
- java - Springboot 应用程序没有从 Spring Config Server 属性中正确获取值
- cupy - 在急流容器内时出现 hdbscan 错误
- c - 如何打印整个 ELF 文件头及其所有信息?
- django - 视图 awesomeinventory.supplier.views.supplierCreateView 没有返回 HttpResponse 对象。它在创建视图中返回 None
- c - 将指针传递给链表的第一个元素时是否需要临时变量?
- c# - System.Management.Automation 与 .NET Core 3.1 不兼容