* glibc обнаружил сообщение о двойном освобождении или повреждении () *! - PullRequest
2 голосов
/ 31 октября 2010

Следующая функция deleteNode при запуске программы получает следующие данные: * обнаружен glibc free (): недопустимый следующий размер (нормальный): 0x000000000103dd90 **

Даже я делаю 'свободным (здесь);'комментарий, я получаю вышеуказанное сообщение.Я не думаю, что другие «бесплатные» звонки провоцируют подобные проблемы.Но я не понимаю, почему это было бы неправильно.: /

struct List *deleteNode(int Code,int i,char* Number)
    {
        struct List *here;
        here=Head;

        for (here; here!=Tail; here=here->next)
        {       
            if ( (here->number==Number) && (here->code==Code) )//found node on the List
            {
                if (here->previous==Head)        //delete from beginning
                {           
                    Head=here->next;
                    here->next->previous=Head;
                }
                else if (here->next==Tail) //delete from the end
                {
                    here->previous->next=Tail;
                    Tail=here->previous;
                }
                else  //delete from the middle of the list
                {   
                    here->previous->next=here->next;
                    here->next->previous=here->previous;
                }
                break;
            }
        }

        free (here);

    }

РЕДАКТИРОВАТЬ: если я использовал и понимаю Valgring хорошо, то проблема в моей основной функции.у меня также есть некоторые «свободные», но я изменил deleteNode перед этим сообщением, поэтому я подумал, что проблема была в функции deleteNode.

Теперь нет free () недопустимого следующего размера .... но, к сожалениюthis: обнаружен glibc *: двойное освобождение или повреждение (out): 0x00007fff1aae9ae0 *: (

Часть основного:

FILE *File;
    if ( ( File=fopen("File.txt","r")) !=NULL )
    {                               
        int li = 0;    
        char *lin = (char *) malloc(MAX_LINE * sizeof(char));


        while(fgets(lin, MAX_LINE, eventFile) != NULL)
        {
            token = linetok(lin, " ");

            if(token != NULL)
            {

                int i,code,nodeID;
            char *number;
            char *event;

                for(i = 0; token[i] != NULL; i += 1)
                {
            code=atoi(token[0]);
            strcpy(event,token[1]);
            nodeID=atoi(token[2]);
            strcpy(number,token[3]) ;

            int i;
            if (!strcmp(event,"add"))
            {       
                add_to_List(code,i,number);
            }
            else if(!strcmp(event,"delete"))
            {       
                             deleteNode(eventNo,i,number);
                    }
            free(event);
            free(phoneNumber);  
        }
                free(token);
            }
            else 
            {
                printf("Error reading line %s\n", lin);
                exit(1);   
            }
        }
    } 
    else 
    {
        printf("Error opening file with the events.\nEXIT!");
        exit(0);
    }

отладка ...

множественное определение main' pro:(.text+0xce0): first defined here /usr/lib/gcc/x86_64-linux-gnu/4.4.1/crtend.o:(.dtors+0x0): multiple definition of DTOR_END 'pro :(. Dtors + 0x8): сначала определено здесь / usr / bin / ld: warning: Невозможно создать раздел .eh_frame_hdr, --eh-frame-hdr игнорируется. / usr / bin / ld: ошибка в pro1 (.eh_frame); нет таблицы .eh_frame_hdr будет создана. collect2: ld вернул 1 состояние выхода

Ответы [ 2 ]

5 голосов
/ 31 октября 2010

«Неверный следующий размер» означает, что glibc обнаружил повреждение в вашей области памяти.

Вы перезаписали ценную учетную информацию, которая хранится между выделенными вами блоками.

Для каждого блока, который malloc дает вам, есть некоторая учетная информация хранится рядом.Когда вы перезаписываете эту информацию, например, записывая 128 символов в 20-символьный буфер, glibc может обнаружить это в следующий раз, когда вы попытаетесь освободить (или, возможно, выделить) некоторую память.

Вам нужно найтипервопричина этой проблемы - это не само по себе освобождение, а именно в этом проблема обнаружена .Где-то часть вашего кода разрушает память, и инструмент анализа памяти, такой как valgrind, будет здесь неоценим.

2 голосов
/ 31 октября 2010

Если узел не найден в списке, вы освободите узел Tail в конце функции, не обновляя Tail, чтобы снова указывать на что-либо действительное.

Дальнейшее использование списка и теперь освобожденного Tail может легко привести к повреждению памяти, которое позже может быть обнаружено glibc с сообщением, подобным тому, которое вы получили.

Также обратите внимание, что в (here->number==Number) вы сравниваете два указателя, а не значения, на которые указывают эти указатели. Я не уверен, что ты этого хочешь.

...