malloc.c:3096: sySMALLOc: ошибка утверждения с использованием указателей

я собираюсь

     malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1)                        * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (   old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
     Aborted

Ошибка, я запустил valgrind и получил

    ==8595==
    ==8595== HEAP SUMMARY:
    ==8595==     in use at exit: 0 bytes in 0 blocks
    ==8595==   total heap usage: 49 allocs, 49 frees, 7,204 bytes allocated
    ==8595==
    ==8595== All heap blocks were freed -- no leaks are possible
    ==8595==
    ==8595== For counts of detected and suppressed errors, rerun with: -v
    ==8595== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 25 from 6)

что привело меня в замешательство. Я считаю, что код вызывает проблему:

    int asn1_encoder(char *bufff[]){

    char av[20];


    char boibuff[] = {0x01, 0x00, 0x00, 0x01};

    char propbuff[] = {0x01};
     \\BACnetConfirmedServiceChoice and BACnetConfirmedServiceRequest types have been ommitted
    long int arb = 0;
    long int arb1 = 0;
    BACnet_Confirmed_Request_PDU_t *bacnetConfirmedPDU;
    int i = 0;
    BACnet_Confirmed_Service_Request_t *service_request;
    BACnetConfirmedServiceChoice_t *service_choice;
    WriteProperty_Request_t *writeProperty;
    BACnetObjectIdentifier_t *objectIdentifier;
    BACnetPropertyIdentifier_t *propertyIdentifier;
    asn_enc_rval_t ec;

    sprintf(av,"test.bin");





      bacnetConfirmedPDU = calloc(1, sizeof(BACnet_Confirmed_Request_PDU_t)); //PDU-TYPE deff

      bacnetConfirmedPDU -> service_request  = calloc(1,             sizeof(BACnet_Confirmed_Service_Request_t));

            objectIdentifier = calloc(1, sizeof(BACnetObjectIdentifier_t));
      service_choice = calloc(1, sizeof(BACnetConfirmedServiceChoice_t)); //Select Service deff

      writeProperty = calloc(1, sizeof(WriteProperty_Request_t)); //Encoded service deff

       bacnetConfirmedPDU -> service_request -> choice.writeProperty.objectIdentifier.buf = calloc(1, sizeof(BACnetObjectIdentifier_t));

      propertyIdentifier = calloc(1, sizeof(BACnetPropertyIdentifier_t));


            if(!bacnetConfirmedPDU){
                    perror("calloc() failed");
                    exit(1);
            }

            bacnetConfirmedPDU -> pdu_type = 1;

            bacnetConfirmedPDU -> service_choice  = BACnetConfirmedServiceChoice_writeProperty;
            printf("the value in service_choice struct is %d\n", bacnetConfirmedPDU->service_choice);


            bacnetConfirmedPDU -> service_request -> present = BACnet_Confirmed_Service_Request_PR_writeProperty;
            bacnetConfirmedPDU -> service_request -> choice.writeProperty.objectIdentifier.buf = boibuff; // BACnetObjectType_binary_output;  //boibuff;


            bacnetConfirmedPDU -> service_request -> choice.writeProperty.objectIdentifier.size = 4;
            printf("boi is %02x\n",bacnetConfirmedPDU -> service_request ->choice.writeProperty.objectIdentifier.buf[1]);

            bacnetConfirmedPDU -> service_request -> choice.writeProperty.propertyIdentifier = BACnetPropertyIdentifier_present_value;

            printf("property ident = %d\n", bacnetConfirmedPDU -> service_request -> choice.writeProperty.propertyIdentifier);
            //bacnetConfirmedPDU -> service_request -> choice.writeProperty.propertyArrayIndex = arb1;
            //printf("the value in proper array is %lu\n",bacnetConfirmedPDU -> service_request -> choice.writeProperty.propertyArrayIndex);
            printf("sef fault before propbuff\n");
            bacnetConfirmedPDU -> service_request -> choice.writeProperty.propertyValue.buf =  propbuff;

            bacnetConfirmedPDU -> service_request -> choice.writeProperty.propertyValue.size = sizeof(propbuff);



            //define port


            FILE *fp = fopen(av, "wb+");
            if(fp == NULL){
            printf("fp is null\n");
            }

            if(!fp){
            perror(av);
            exit(1);
            }

            ec = der_encode(&asn_DEF_BACnet_Confirmed_Request_PDU, bacnetConfirmedPDU, write_out, fp);

            if(fp == NULL)
            {
            printf("fp null\n");
            }

             if(!fp){
            perror(av);
            exit(1);
            }

            ec = der_encode(&asn_DEF_BACnet_Confirmed_Request_PDU, bacnetConfirmedPDU, write_out, fp);

            if(fp == NULL)
            {
            printf("fp null\n");

            }

            printf("the file is closed\n");
            int end = fseek(fp, 0, SEEK_END);
            end = ftell(fp);
            fseek(fp, 0, SEEK_SET);
            printf("fseek is happening\n");
            //int end = ftell(fp);
             if(fp == NULL)
            {
            printf("*******************bufff is null***************************\n");
            }

            printf("end equals %d\n", end);
            //printf("just before fgetc\n");
            //for(i = 0; i<= 35 ; i++)
         for(i = 0; i <  end; i++)
         {

            if(feof(fp)){
            printf("we're a broken family\n");
            break;
            }
            if(i> maxlen){
            printf(" buff is full\n");
            break;
            }
             }

            }

            fclose(fp);
            if(ec.encoded == -1){
                    fprintf(stderr, "could not encode ConfirmedRequest_PDU at (%s)\n",
                    ec.failed_type ? ec.failed_type -> name : "unknown");
                            exit(1);
            }else{
                    fprintf(stderr, "Created %s with BER encoded ConfirmedRequestPDU\n", av);
                    }

            xer_fprint(stdout, &asn_DEF_BACnet_Confirmed_Request_PDU, bacnetConfirmedPDU);

            free(bacnetConfirmedPDU);
            free(bacnetConfirmedPDU -> service_request);
            return i;
            }

Я не могу определить, в чем проблема, я попытался освободить все переменные, которые я вызывал. тем не менее, все эти структуры являются членами bacnetConfirmedPDU, поэтому не должно ли быть достаточно освобождения только bacnetConfirmedPDU? также строка:

               free((bacnetConfirmedPDU -> service_request);

это небольшая сумма для беспокойства, так как это может быть двойной бесплатно? Мой вопрос в том, какие еще есть варианты для проверки утечек памяти и связанных нарушений, кроме valgrind? кроме того, есть ли что-то явно очевидное, что может вызвать ошибку утверждения? Любые предложения приветствуются, также, если у кого-то есть предложения по обнаружению ошибок, пример также будет очень признателен. Спасибо


person user3681077    schedule 23.12.2014    source источник
comment
В чем смысл if(fp == NULL) ... if(!fp)? printf может очень легко модифицировать errno, делая perror совершенно бесполезным. Если вы собираетесь это сделать, вы должны вызвать perror перед printf, и вы можете поместить их в одно и то же предложение if.   -  person William Pursell    schedule 23.12.2014
comment
Если я правильно помню, вы должны сопоставлять каждый вызов calloc с free и в обратном порядке. Итак, каково значение bacnetConfirmedPDU -> service_request после освобождения структуры?   -  person Chris O    schedule 23.12.2014


Ответы (1)


В вашем коде:

 free(bacnetConfirmedPDU);

 free(bacnetConfirmedPDU -> service_request);

Сначала вы освобождаете указатель структуры, а затем освобождаете переменную-член, если память этой структуры bacnetConfirmedPDU уже восстановлена ​​системой, это означает, что значение bacnetConfirmedPDU -> service_request может быть изменено, это может быть проблемой. Итак, вам следует:

free(bacnetConfirmedPDU -> service_request);   
free(bacnetConfirmedPDU);
person Matt    schedule 23.12.2014
comment
теперь, если элементы исходной структуры содержат дополнительные элементы, их также нужно сначала освободить? - person user3681077; 23.12.2014