我正在
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-ed的所有变量。然而,所有这些结构都是bacnetConfirmedPDU的成员,所以,这样,不应该只释放bacnetConfirmedPDU就够了吗?这一行:
free((bacnetConfirmedPDU -> service_request);
有点担心,因为它可能是免费的双倍?我的问题是,除了valgrind之外还有哪些其他选项可用于检查内存泄漏和绑定违规?还有,有什么明显可能会导致断言错误吗?任何建议都非常感谢,如果有人确实有错误检测建议,一个例子也将非常感激。谢谢
答案 0 :(得分:2)
在您的代码中:
free(bacnetConfirmedPDU);
free(bacnetConfirmedPDU -> service_request);
首先释放结构的指针,然后释放成员变量,如果系统已经重新收集了该结构bacnetConfirmedPDU
的内存,则意味着bacnetConfirmedPDU -> service_request
的vaule可能会被更改,这可能是问题所在。所以你应该:
free(bacnetConfirmedPDU -> service_request);
free(bacnetConfirmedPDU);