c:3096:sYSMALLOc:使用指针的断言错误
我要走了c:3096:sYSMALLOc:使用指针的断言错误,c,valgrind,assertion,C,Valgrind,Assertion,我要走了 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
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;
}
是不是有点担心,因为它可能是一个双重免费?我的问题是,除了valgrind之外,还有什么其他选项可以检查内存泄漏和绑定冲突?另外,是否有任何明显的东西会导致断言错误?非常感谢您的任何建议,而且,如果有人有错误检测建议,请举个例子。感谢您的代码:
free(bacnetConfirmedPDU);
free(bacnetConfirmedPDU -> service_request);
首先释放结构的指针,然后释放成员变量,如果该结构的内存bacnetConfirmedPDU
已被系统回收,这意味着bacnetConfirmedPDU->service\u request
的值可能会更改,这可能是问题所在。所以你应该:
free(bacnetConfirmedPDU -> service_request);
free(bacnetConfirmedPDU);
如果(fp==NULL)
有什么意义。。。如果(!fp)
?printf可以很容易地修改errno,使得perror完全无用。如果你要这样做,你必须在printf之前调用perror,你也可以把它们放在同一个If
子句中。如果我没记错的话,你应该将对calloc
的每次调用都与free
匹配,并且顺序相反。那么,在释放结构之后,bacnetConfirmedPDU->service\u request
的值是多少?现在,如果原始结构的成员包含其他成员,那么也必须首先释放这些成员?
free(bacnetConfirmedPDU -> service_request);
free(bacnetConfirmedPDU);