在线程释放链接列表(队列)中的内存期间的段错误

时间:2013-03-02 18:53:34

标签: multithreading segmentation-fault free

我创建了一个帖子。主要功能是创建一个元素并将其附加到队列的尾部/尾部。线程正在从Head / Start读取列表,并在之后释放内存。

我有以下代码:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

void *print_message_function( void *ptr );

typedef struct stCheckFree
{
    char name[30];
    int doneflag;
    struct stCheckFree *next;
}CheckFree;

CheckFree *gHead=NULL;
CheckFree *gTail=NULL;

int main()
{
    pthread_t thread1;
    char *message1 = "Thread 1";
    int iret1;
    unsigned long TestCount=1;

    CheckFree *pCurr=NULL;
    CheckFree *pTemp=NULL;

    iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);

    while(1)
    {
        pCurr=malloc(sizeof(CheckFree));
        memset(pCurr,0,sizeof(CheckFree));

        printf("Malloc\n");
        sprintf(pCurr->name,"Test-%ld",TestCount); TestCount++;
        pCurr->doneflag=0;
        pCurr->next=NULL;

        pTemp=gTail;
        gTail=pCurr;
        if(pTemp) pTemp->next=gTail;

        if(!gHead)
        {
            gHead=gTail;
        }

    }

    return 0;
}

void *print_message_function( void *ptr )
{
    CheckFree *pTrav;

    while(1)
    {
        pTrav=gHead;
        if(pTrav)
        {
            printf("[%s]\n",pTrav->name);
            pTrav->doneflag=1;

            gHead=gHead->next;
            free(pTrav);
        }
    }
}

当我运行代码时,它给了我一个段错误。可能是什么问题? 请帮忙!

感谢。

PS-如果我删除了free(),它的运行非常出色!!!

-------------------------------------------- ---------------------------------------
---编辑1 ---
----------------------------------------------- ------------------------------------

我不确定这是否是修复,但我需要来自其他 stackoverflow 成员的更多输入。

void *print_message_function( void *ptr )
{
    CheckFree *pTrav;

    while(1)
    {
        pTrav=gHead;
        if(pTrav)
        {
            printf("[%s]\n",pTrav->name);
            pTrav->doneflag=1;

            gHead=gHead->next;

            if(!gHead) gTail=NULL;                /* NEW CODE */

            free(pTrav);
            sleep(0.7);
        }
    }
}

请帮助,因为它很重要! :) 再次感谢。

-------------------------------------------- ---------------------------------------
---编辑2 ---
----------------------------------------------- ------------------------------------

代码更改: -     if(!gHead)gTail = NULL; / *新代码* / 通过重新初始化NULL来破坏数据。

只需执行以下代码更改即可看到它:

  

...
PTEMP = gTail;
      gTail = pCurr;
      if(pTemp)pTemp-&gt; next = gTail;
      if(!gTail)printf(“数据丢失\ n”);
      如果(!gHead)
      {
...

请帮我纠正这个问题...

-------------------------------------------- ---------------------------------------
---编辑3 ---
----------------------------------------------- ------------------------------------
在@ wazy建议使用互斥锁后,我按如下方式更新了代码: -

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

void * thread_function( void *ptr );

typedef struct stCheckFree
{
    char name[30];
    int doneflag;
    struct stCheckFree *next;
}CheckFree;

pthread_mutex_t lock;    // EDIT 3

CheckFree *gHead=NULL;
CheckFree *gTail=NULL;

int main()
{
    pthread_t thread1;
    char *message1 = "Thread 1";
    int  iret1;
    unsigned long TestCount=1;

    CheckFree *pCurr=NULL;
    CheckFree *pTemp=NULL;

    if (pthread_mutex_init(&lock, NULL) != 0)    // EDIT 3
    {
        printf("\n mutex init failed\n");
        return 1;
    }

    iret1 = pthread_create( &thread1, NULL,  thread_function, (void*) message1);

    while(1)
    {
        pCurr=malloc(sizeof(CheckFree));
        memset(pCurr,0,sizeof(CheckFree));

        sprintf(pCurr->name,"Test-%ld",TestCount); TestCount++;
        pCurr->doneflag=0;
        pCurr->next=NULL;

        pTemp=gTail;
        gTail=pCurr;
        if(pTemp) pTemp->next=gTail;


        //pthread_mutex_lock(&lock);    // EDIT 3(commented out)
        if(!gHead)
        {
            pthread_mutex_lock(&lock);    // EDIT 4
            gHead=gTail;
            pthread_mutex_unlock(&lock);    // EDIT 4
        }
        //pthread_mutex_unlock(&lock);    // EDIT 3(commented out)
    }

    pthread_join( thread1, NULL);
    printf("Thread 1 returns: %d\n",iret1);

    return 0;
}

void * thread_function( void *ptr )
{
    CheckFree *pTrav;

    while(1)
    {
        pTrav=gHead;
        if(pTrav)
        {
            //printf("[%s]\n",pTrav->name);
            pTrav->doneflag=1;

            gHead=gHead->next;
            if(!gHead) sleep(1);//gTail=NULL;
            free(pTrav);
        }
    }
}

我是否在正确的轨道上????? 感谢!!!

1 个答案:

答案 0 :(得分:1)

运行代码会让我从glibc获得双重免费或损坏(fasttop)。查看您的代码,我发现您在thread1和主线程中都使用了gHead。这似乎是一个多线程同步问题。