队列字符串内存的正确处理是什么

问题描述 投票:0回答:1

我为我的多线程程序构建了自己的任务队列,但代码中某处的内存分配出现错误。

在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
是内存 分配器。但我可能是错的。即使端点在任务完成后被正确释放,泄漏仍然发生在某处。

c multithreading memory memory-leaks
1个回答
0
投票

阅读你的代码并思考其操作是很好的..

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)
© www.soinside.com 2019 - 2024. All rights reserved.