我为我的多线程程序构建了自己的任务队列,但代码中某处的内存分配出现错误。
在main.c中:
#include <pthread.h>
#include <task_queue.h>
#include <stdlib.h>
#include <curl.h>
typedef struct Threadargs {
TaskQueue *q;
CURLM *multi_handle;
pthread_mutex_t lock;
} Threadargs;
void *do_task(void *args);
int main(){
int len = 5;
char *arr = {
"filename.txt",
"endpoint",
"endpoint",
"endpoint",
"endpoint"
};
TaskQueue *q = queueFromArr(arr, 1, len);
curl_global_init(CURL_GLOBAL_ALL);
CURLM *multi_handle = curl_multi_init();
curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
Threadargs *targs = malloc(sizeof(Threadargs));
targs->q = q;
targs->multi_handle = multi_handle;
pthread_mutex_init(&targs->lock, NULL);
pthread_t threads[len];
for(int i = 0; i < len; ++i){
pthread_create(&threads[i], NULL, do_task, q);
}
while(
for(int i = 0; i < len; ++i){
pthread_join(threads[i], NULL);
}
free(threads);
pthread_mutex_destroy(&targs->lock);
return 0;
}
void *do_task(void *args){
Threadargs *targs = (Threadargs*)args;
TaskQueue *q = targs->q;
CURLM *multi = targs->multi_handle;
char *endpoint;
while((endpoint = (char *)queueDequeue(queue)) != NULL){
CURL *handle = curl_easy_init();
// set options for curl
curl_easy_setopt(handle, CURLOPT_URL, endpoint);
pthead_mutex_lock(&targs->lock);
CURLcode res = curl_multi_add_handle(multi, handle);
pthread_mutex_unlock(&targs->lock);
if(res != CURLM_OK){
// print out error here
return (void *) 1;
}
}
return (void *) 0;
}
在task_queue.h中:
typedef struct Task{
char *endpoint;
struct Task *next;
} Task;
typedef struct TaskQueue{
Task *head;
Task *tail;
pthread_mutex_t lock;
} TaskQueue;
TaskQueue *queueInit() {
TaskQueue *tqueue = malloc(sizeof(TaskQueue));
if(!tqueue)
return NULL;
tqueue->head = NULL;
tqueue->tail = NULL;
pthread_mutex_init(&tqueue->lock,NULL);
return tqueue;
}
void queueEnqueue(TaskQueue *queue, char *endpoint) {
Task *task = malloc(sizeof(Task));
task->endpoint = endpoint;
task->next = NULL;
pthread_mutex_lock(&queue->lock);
if (queue->tail == NULL)
{
queue->head = queue->tail = task;
}
else
{
queue->tail->next = task;
queue->tail = task;
}
pthread_mutex_unlock(&queue->lock);
}
TaskQueue *queueFromArr(char **arr, int start, int end) {
TaskQueue *queue;
if((queue = queueInit()) == NULL)
return NULL;
for(int i = start; i < end; ++i){
char *point = strdup(arr[i]);
queueEnqueue(queue,point);
}
return queue;
}
// Dequeue a task from the queue
void *queueDequeue(TaskQueue *queue) {
pthread_mutex_lock(&queue->lock);
if (queue->head == NULL) {
pthread_mutex_unlock(&queue->lock);
return NULL;
}
Task *temp = queue->head;
char *data = strdup(temp->endpoint);
queue->head = temp->next;
if (queue->head == NULL)
queue->tail = NULL;
free(temp);
pthread_mutex_unlock(&queue->lock);
return data;
}
导致以下错误:
==62212== 440 bytes in 5 blocks are definitely lost in loss record 147 of 510
==62212== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==62212== by 0x1204675E: make_call (main.c:316)
==62212== by 0x4A36AC2: start_thread (pthread_create.c:442)
==62212== by 0x4AC7A03: clone (clone.S:100)
我最初认为它与
strdup
有关,但通常情况下,如果它是它分配的内存 - 它会说 strdup
是内存 分配器。但我可能是错的。即使端点在任务完成后被正确释放,泄漏仍然发生在某处。
阅读你的代码并思考其操作是很好的..
TaskQueue *queueFromArr(char **arr, int start, int end) {
/* stuff */
char *point = strdup(arr[i]); // <= FIRST heap allocation (making a copy)
queueEnqueue(queue,point);
...然后...
void *queueDequeue(TaskQueue *queue) {
/* stuff */
char *data = strdup(temp->endpoint); // a SECOND allocated copy (why?)
/* stuff */
free(temp); // <= abandoning the FIRST allocated block (memory leak)