我从 valgrind 收到 25 个错误。其中 23 个错误来自同一上下文。我没有失忆,但我无法弄清楚确切的问题出在哪里。我得到了我想要的确切输出,但我仍然无法解决内存错误。
我添加了我的 valgrind 输出和相关代码部分。
Valgrind 输出
HEAP SUMMARY:
==30142== in use at exit: 0 bytes in 0 blocks
==30142== total heap usage: 76 allocs, 77 frees, 2,146 bytes allocated
==30142==
==30142== All heap blocks were freed -- no leaks are possible
==30142==
==30142== ERROR SUMMARY: 25 errors from 3 contexts (suppressed: 0 from 0)
==30142==
==30142== 1 errors in context 1 of 3:
==30142== Invalid free() / delete / delete[] / realloc()
==30142== at 0x4C2B06D: free (vg_replace_malloc.c:540)
==30142== by 0x400D79: main (pa2.c:201)
==30142== Address 0x52063e0 is 0 bytes inside a block of size 24 free'd
==30142== at 0x4C2B06D: free (vg_replace_malloc.c:540)
==30142== by 0x4009D6: byte_to_char (pa2.c:75)
==30142== by 0x400CBC: main (pa2.c:157)
==30142== Block was alloc'd at
==30142== at 0x4C2C089: calloc (vg_replace_malloc.c:762)
==30142== by 0x400DE6: createNode (tree.c:10)
==30142== by 0x4009B3: byte_to_char (pa2.c:73)
==30142== by 0x400CBC: main (pa2.c:157)
==30142==
==30142==
==30142== 1 errors in context 2 of 3:
==30142== Invalid read of size 1
==30142== at 0x400F0A: peek (stack.c:27)
==30142== by 0x40083C: remove_zeroes (pa2.c:27)
==30142== by 0x400CCE: main (pa2.c:165)
==30142== Address 0x5206490 is 0 bytes inside a block of size 24 free'd
==30142== at 0x4C2B06D: free (vg_replace_malloc.c:540)
==30142== by 0x4008E5: byte_to_char (pa2.c:50)
==30142== by 0x400CBC: main (pa2.c:157)
==30142== Block was alloc'd at
==30142== at 0x4C2C089: calloc (vg_replace_malloc.c:762)
==30142== by 0x400DE6: createNode (tree.c:10)
==30142== by 0x4008C2: byte_to_char (pa2.c:48)
==30142== by 0x400CBC: main (pa2.c:157)
==30142==
==30142==
==30142== 23 errors in context 3 of 3:
==30142== Invalid read of size 1
==30142== at 0x400D1F: main (pa2.c:175)
==30142== Address 0x52063e0 is 0 bytes inside a block of size 24 free'd
==30142== at 0x4C2B06D: free (vg_replace_malloc.c:540)
==30142== by 0x4009D6: byte_to_char (pa2.c:75)
==30142== by 0x400CBC: main (pa2.c:157)
==30142== Block was alloc'd at
==30142== at 0x4C2C089: calloc (vg_replace_malloc.c:762)
==30142== by 0x400DE6: createNode (tree.c:10)
==30142== by 0x4009B3: byte_to_char (pa2.c:73)
==30142== by 0x400CBC: main (pa2.c:157)
==30142==
==30142== ERROR SUMMARY: 25 errors from 3 contexts (suppressed: 0 from 0)
主函数调用(及之后)
int main(int argc, char ** argv){
printf("In Main\n");
if(argc != 7){
printf("args doesn't match expected value\n");
return EXIT_FAILURE;
}
FILE *fptr = fopen(argv[1], "rb");
if(fptr == NULL){
return EXIT_FAILURE;
}
long int size_compressed; //size_compressed: Number of bytes in compressed file
long int size_topology; //size_topology: Number of bytes topology uses
long int size_original; //size_original: Number of bytes in the uncompressed file
fread(&size_compressed, sizeof(long int) , 1, fptr);
fread(&size_topology, sizeof(long int), 1, fptr);
fread(&size_original, sizeof(long int), 1, fptr);
int size = sizeof(char)* sizeof(long int) * size_topology;
printf("Size Compressed: %ld\n", size_compressed);
printf("Size Topology: %ld\n", size_topology);
printf("Size Original: %ld\n", size_original);
unsigned char *buffer;
int *val;
buffer = (unsigned char*) malloc(sizeof(unsigned char) * size_topology);
size_t bytes_read = fread(buffer, sizeof(unsigned char), size_topology, fptr);
//val = (int*) malloc(sizeof(int) * (size_topology));
val = (int*) malloc(size);
fclose(fptr);
if(bytes_read != size_topology){
printf("Topology size and read bytes don't match!");
}
for(int i=0; i < size_topology; i++){
val[i] = buffer[i];
}
char *toVal; //toVal: char array of 8 to store every bit of a byte
char *all_topology; //all_topology: char array of 8 * size_topology to store ALL bits of topology.
int j; //j: index for all_topology
// toVal = (char*) malloc(sizeof(char)* sizeof(int));
// all_topology = (char*) malloc(size);
toVal = (char*) malloc(size);
all_topology = (char*) malloc(size);
//For Loop where conversion of the bytes in val to bits happen, output is stored in all_topology
for(int i=0; i < size_topology; i++){
j = i*8;
byte_to_bits(val[i], toVal);
for(int k=0; k< 8;k++){
all_topology[j] = toVal[k];
printf("%d", all_topology[j]);
j++;
}
printf("\n");
}
//-----NO MEMORY ISSUES UP TO HERE-----
//-----NO MEMORY ISSUES UP TO HERE-----
//-----NO MEMORY ISSUES UP TO HERE-----
Snode* stack = NULL;
//LEAK STARTS HERE
int numOfBytes = byte_to_char(all_topology, &stack, size);
remove_zeroes(&stack);
printf("NumOfBYtes: %d\n", numOfBytes);
Tnode* node = NULL;
Snode* reverse_stack = NULL;
int flag = 1;
while(flag){
node = pop(&stack);
if(node == NULL){
break;
}
printf("%c", node->id);
printf("\n");
push(&reverse_stack, node);
}
//FREE
Tnode* tmp = NULL;
while(1){
if(isEmpty(reverse_stack)){
break;
} else{
tmp = pop(&reverse_stack);
}
}
free(tmp);
free(all_topology);
free(toVal);
free(buffer);
free(val);
return EXIT_SUCCESS;
}
字节到字符
int byte_to_char(char *topology, Snode** stack, int size){
int numOfBytes = 0;
char ascii_concat[8];
unsigned char ascii_val = 0;
int countChar =0;
Tnode* node = NULL;
Tnode* node1 = NULL;
Tnode* node2 = NULL;
//char char_top[80];
for(int i=0; i < size; i++){
if(topology[i] == 0){
//char_top[i] = 48; //ASCII Value of 0
node = createNode(48, 0);
push(stack, node);
free(node);
numOfBytes++;
} else{
ascii_val = 0xff;
//char_top[i] = 49; //ASCII Value of 1
node1 = createNode(49, 1);
push(stack, node1);
free(node1);
numOfBytes++;
i++; //skip the leaf node indicator
countChar++;
for(int j=0; j<8; j++){
ascii_concat[j] = topology[i++];
}
i--;
for(int j=0; j<8; j++){
if(ascii_concat[j] == 0){
ascii_val = (1 << (j)) ^ ascii_val;
}
}
//printf("%c\n", ascii_val);
//Create leaf node
//char_top[i] = ascii_val;
//byte_to_char (pa2.c:73)
node2 = createNode(ascii_val, 2);
push(stack, node2);
free(node2);
numOfBytes = numOfBytes + 8;
//count characters in header
}
countChar++;
}
// printf("chars\n");
// for(int i=0;i < 24; i++){
// printf("%c", char_top[i]);
// }
// free(node);
return numOfBytes;
}
创建节点
Tnode* createNode(char id, int flag){
Tnode* n = (Tnode*) calloc(1, sizeof(Tnode));
//Tnode* n = (Tnode*) malloc(sizeof(Tnode));
n->id = id;
n->flag = flag;
return n;
}
所有三个错误上下文都是由于代码中将节点放入堆栈后删除节点的 2 个位置造成的:
for(int i=0; i < size; i++){
if(topology[i] == 0){
//char_top[i] = 48; //ASCII Value of 0
node = createNode(48, 0);
push(stack, node);
free(node); // the target of node is still referenced
numOfBytes++;
} else{
ascii_val = 0xff;
//char_top[i] = 49; //ASCII Value of 1
node1 = createNode(49, 1);
push(stack, node1);
free(node1); // the target of node is still referenced
您需要删除这两个对 free 的调用,而不是删除 free 节点,直到弹出堆栈上的引用。