2014-12-23 1 views
0

Я получаю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; 
      } 

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

   free((bacnetConfirmedPDU -> service_request); 

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

+0

В чем смысл 'if (fp == NULL) ... if (! Fp)'? Printf может очень легко изменить errno, делая perror совершенно бесполезным. Если вы собираетесь это сделать, вы должны * вызвать perror перед printf, и вы можете также разместить их в одном и том же предложении if. –

+0

Если я правильно помню, вы должны соответствовать каждому вызову 'calloc' с' free' и в обратном порядке. Итак, какова ценность 'bacnetConfirmedPDU -> service_request' после того, как структура была освобождена? –

ответ

2

В коде:

free(bacnetConfirmedPDU); 

free(bacnetConfirmedPDU -> service_request); 

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

free(bacnetConfirmedPDU -> service_request); 
free(bacnetConfirmedPDU); 
+0

теперь, если члены исходной структуры содержат дополнительные члены, они также должны быть освобождены в первую очередь? – user3681077

+0

Да, если элемент является указателем. – Matt