【发布时间】:2021-04-06 15:32:04
【问题描述】:
我正在尝试将我预先构建的树打印到文件中,但我不断收到此错误。我对C很陌生,所以我迷路了。如果节点为 NULL,我尝试打印语句并执行从函数返回的 if-else 语句,但它仍然无法正常工作。该代码适用于树中最多 19 个节点,但不适用于 199、1999 和 19999 个节点。我也尝试使用 valgrind,但在理解 valgrind 发出的消息时遇到问题。我使用的代码是:
代码是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "stack.h"
#include <errno.h>
extern int errno;
void preprint(treenode *node, FILE *fpw)
{
if (node == NULL)
{
return;
}
int i = 0;
int flagsink = node->flagsink;
if (node != NULL)
{
switch (flagsink)
{
case 1:
fprintf(fpw, "%d(%le)\n", node->label, node->sinkCap);
// printf("here1\n");
//printf("Leaf printed: %d(%le)\n", node->label, node->sinkCap);
break;
case 0:
fprintf(fpw, "(%le %le)\n", node->leftl, node->rightl);
// printf("here\n");
//printf("non leaf printed: (%le %le)\n", node->leftl, node->rightl);
break;
}
//printf("line printed\n");
//if (node->left == NULL){
// printf("\nError is HERE\n");
// return;
//}
preprint(node->left, fpw);
//if (node->right == NULL){
// printf("\nError is HERE\n");
// return;
//}
//else{
preprint(node->right, fpw);
//}
}
}
void preprint2(treenode *node, FILE *fpw2)
{
if (node == NULL)
{
return;
}
int flagsink = node->flagsink;
if (node != NULL)
{
int i1, i2;
double res1, cap1, res2, cap2;
switch (flagsink)
{
case 1:
//int i;
i1 = node->label;
//double res, cap;
res1 = node->nres;
cap1 = node->capacitance;
fwrite(&i1, 2, sizeof(int), fpw2);
fwrite(&res1, 2, sizeof(double), fpw2);
fwrite(&cap1, 2, sizeof(double), fpw2);
printf("here3\n");
//printf("Leaf res printed: %d%le%le\n", node->label, node->nres, node->capacitance);
break;
case 0:
//int i;
//double res, cap;
i2 = -1;
res2 = node->nres;
cap2 = node->capacitance;
fwrite(&i2, 2, sizeof(int), fpw2);
fwrite(&res2, 2, sizeof(double), fpw2);
fwrite(&cap2, 2, sizeof(double), fpw2);
printf("here4\n");
//fwrite(fpw, "(%d%le%le)\n", -1, node->nres, node->capacitance);
//printf("non leaf res printed: (%d %le %le)\n", -1, node->nres, node->capacitance);
break;
}
preprint2(node->left, fpw2);
preprint2(node->right, fpw2);
}
return;
}
void calc_cap(treenode *root, double sourceres, double unitres, double unitcap)
{
if (root == NULL)
{
return;
}
if (root != NULL)
{
int flagsink = root->flagsink;
if (root->rflag == 1)
{
root->nres = sourceres;
root->capacitance = (((root->leftl) * unitcap) / 2) + (((root->rightl) * unitcap) / 2);
}
else
{
switch (flagsink)
{
case 1:
root->nres = root->parent * unitres;
root->capacitance = (((root->parent) * unitcap) / 2) + root->sinkCap;
break;
case 0:
root->nres = root->parent * unitres;
root->capacitance = (((root->leftl) * unitcap) / 2) + (((root->rightl) * unitcap) / 2) + (((root->parent) * unitcap) / 2);
}
}
}
}
void bt_build(FILE *fp, FILE *fpw, FILE *fpw2)
{
double sourceres;
double unitres;
double unitcap;
//char ch;
int errnum;
int stack_size = 1000;
rewind(fp);
printf("here is okay\n");
stnode *stack = NULL;
stack = cr_stack(stack_size);
printf("Stack is allocated\n");
if (stack == NULL)
{
errnum = errno;
fprintf(stderr, "Stack build function failed: %s\n", strerror(errnum));
return;
}
//stnode *stack = NULL;
//stack = malloc(sizeof(stnode));
//if(stack == NULL){
// printf("Mallocing error\n");
//}
printf("Try this\n");
treenode *right;
treenode *left;
double leftl;
double rightl;
double sinkCap;
int label;
if (fscanf(fp, "%le %le %le\n", &sourceres, &unitres, &unitcap) == 3)
{
printf("here\n");
while (!feof(fp))
{
//ch = fgetc(fp);
//if(ch != '('){
if (fscanf(fp, "(%le %le)\n", &leftl, &rightl) == 2)
{
//int value = fscanf(fp, "%le %le)\n", &leftl, rightl);
int flagsink = 0;
//printf("(%le %le)\n", leftl, rightl);
treenode *placeholder = NULL;
//int value = fscanf(fp, "%le %le)\n", &leftl, rightl);
right = pop(stack);
left = pop(stack);
placeholder = newNode(0, 0, leftl, rightl, left, right, flagsink);
right->parent = placeholder->rightl;
left->parent = placeholder->leftl;
push(stack, placeholder);
}
else if (fscanf(fp, "%d(%le)\n", &label, &sinkCap) == 2)
{
//printf("%d(%le)\n", label, sinkCap);
//fseek(fp, -1L, SEEK_CUR);
int flagsink = 1;
treenode *placeholder = NULL;
//int value = fscanf(fp, "%d(%le)\n", &label, &sinkCap);
placeholder = newNode(label, sinkCap, 0, 0, NULL, NULL, flagsink);
push(stack, placeholder);
}
else
{
break;
}
}
}
treenode *root = NULL;
root = pop(stack);
preprint(root, fpw);
root->parent = sourceres;
root->rflag = 1;
//calc_cap(root, sourceres, unitres, unitcap);
printf("\nBACKTRACK\n");
//preprint2(root, fpw2);
destroy(root);
printf("\nTree destroyed\n");
return;
}
void destroy(treenode *root)
{
if (root == NULL)
{
return;
}
free(root);
destroy(root->left);
destroy(root->right);
}
Valgrind 给我以下信息:
==157624== Invalid read of size 8
==157624== at 0x40111D: destroy (solution.c:192)
==157624== by 0x401128: destroy (solution.c:192)
==157624== by 0x401138: destroy (solution.c:193)
==157624== by 0x4010EC: bt_build (solution.c:181)
==157624== by 0x4011EA: main (pa3.c:25)
==157624== Address 0x520ce40 is 16 bytes inside a block of size 88 free'd
==157624== at 0x4C2B06D: free (vg_replace_malloc.c:540)
==157624== by 0x401118: destroy (solution.c:191)
==157624== by 0x401128: destroy (solution.c:192)
==157624== by 0x401138: destroy (solution.c:193)
==157624== by 0x4010EC: bt_build (solution.c:181)
==157624== by 0x4011EA: main (pa3.c:25)
==157624== Block was alloc'd at
==157624== at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==157624== by 0x4009F3: newNode (stack.c:28)
==157624== by 0x400FC7: bt_build (solution.c:153)
==157624== by 0x4011EA: main (pa3.c:25)
==157624==
==157624== Invalid read of size 8
==157624== at 0x40112D: destroy (solution.c:193)
==157624== by 0x401128: destroy (solution.c:192)
==157624== by 0x401138: destroy (solution.c:193)
==157624== by 0x4010EC: bt_build (solution.c:181)
==157624== by 0x4011EA: main (pa3.c:25)
==157624== Address 0x520ce38 is 8 bytes inside a block of size 88 free'd
==157624== at 0x4C2B06D: free (vg_replace_malloc.c:540)
==157624== by 0x401118: destroy (solution.c:191)
==157624== by 0x401128: destroy (solution.c:192)
==157624== by 0x401138: destroy (solution.c:193)
==157624== by 0x4010EC: bt_build (solution.c:181)
==157624== by 0x4011EA: main (pa3.c:25)
==157624== Block was alloc'd at
==157624== at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==157624== by 0x4009F3: newNode (stack.c:28)
==157624== by 0x400FC7: bt_build (solution.c:153)
==157624== by 0x4011EA: main (pa3.c:25)
==157624==
==157624== Invalid read of size 8
==157624== at 0x40112D: destroy (solution.c:193)
==157624== by 0x401138: destroy (solution.c:193)
==157624== by 0x4010EC: bt_build (solution.c:181)
==157624== by 0x4011EA: main (pa3.c:25)
==157624== Address 0x520d338 is 8 bytes inside a block of size 88 free'd
==157624== at 0x4C2B06D: free (vg_replace_malloc.c:540)
==157624== by 0x401118: destroy (solution.c:191)
==157624== by 0x401138: destroy (solution.c:193)
==157624== by 0x4010EC: bt_build (solution.c:181)
==157624== by 0x4011EA: main (pa3.c:25)
==157624== Block was alloc'd at
==157624== at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==157624== by 0x4009F3: newNode (stack.c:28)
==157624== by 0x400FC7: bt_build (solution.c:153)
==157624== by 0x4011EA: main (pa3.c:25)
==157624==
==157624== Invalid read of size 8
==157624== at 0x40111D: destroy (solution.c:192)
==157624== by 0x401138: destroy (solution.c:193)
==157624== by 0x401138: destroy (solution.c:193)
==157624== by 0x4010EC: bt_build (solution.c:181)
==157624== by 0x4011EA: main (pa3.c:25)
==157624== Address 0x520d2a0 is 16 bytes inside a block of size 88 free'd
==157624== at 0x4C2B06D: free (vg_replace_malloc.c:540)
==157624== by 0x401118: destroy (solution.c:191)
==157624== by 0x401138: destroy (solution.c:193)
==157624== by 0x401138: destroy (solution.c:193)
==157624== by 0x4010EC: bt_build (solution.c:181)
==157624== by 0x4011EA: main (pa3.c:25)
==157624== Block was alloc'd at
==157624== at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==157624== by 0x4009F3: newNode (stack.c:28)
==157624== by 0x400FC7: bt_build (solution.c:153)
==157624== by 0x4011EA: main (pa3.c:25)
==157624==
==157624== Invalid read of size 8
==157624== at 0x40112D: destroy (solution.c:193)
==157624== by 0x401138: destroy (solution.c:193)
==157624== by 0x401138: destroy (solution.c:193)
==157624== by 0x4010EC: bt_build (solution.c:181)
==157624== by 0x4011EA: main (pa3.c:25)
==157624== Address 0x520d298 is 8 bytes inside a block of size 88 free'd
==157624== at 0x4C2B06D: free (vg_replace_malloc.c:540)
==157624== by 0x401118: destroy (solution.c:191)
==157624== by 0x401138: destroy (solution.c:193)
==157624== by 0x401138: destroy (solution.c:193)
==157624== by 0x4010EC: bt_build (solution.c:181)
==157624== by 0x4011EA: main (pa3.c:25)
==157624== Block was alloc'd at
==157624== at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==157624== by 0x4009F3: newNode (stack.c:28)
==157624== by 0x400FC7: bt_build (solution.c:153)
==157624== by 0x4011EA: main (pa3.c:25)
==157624==
Tree destroyed
==157624==
==157624== HEAP SUMMARY:
==157624== in use at exit: 8 bytes in 1 blocks
==157624== total heap usage: 203 allocs, 202 frees, 19,224 bytes allocated
==157624==
==157624== LEAK SUMMARY:
==157624== definitely lost: 8 bytes in 1 blocks
==157624== indirectly lost: 0 bytes in 0 blocks
==157624== possibly lost: 0 bytes in 0 blocks
==157624== still reachable: 0 bytes in 0 blocks
==157624== suppressed: 0 bytes in 0 blocks
==157624== Rerun with --leak-check=full to see details of leaked memory
==157624==
==157624== For lists of detected and suppressed errors, rerun with: -s
==157624== ERROR SUMMARY: 796 errors from 35 contexts (suppressed: 0 from 0)
错误是:
*** Error in `a.out': double free or corruption (out): 0x0000000000f746f0 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x81299)[0x7f0b8ae97299]
a.out[0x401119]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x401129]
a.out[0x4010ed]
a.out[0x4011eb]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f0b8ae38555]
a.out[0x400819]
======= Memory map: ========
00400000-00402000 r-xp 00000000 fd:03 2082285 /home/shay/a/navani/ece368/pao3/pa3/a.out
00601000-00602000 r--p 00001000 fd:03 2082285 /home/shay/a/navani/ece368/pao3/pa3/a.out
00602000-00603000 rw-p 00002000 fd:03 2082285 /home/shay/a/navani/ece368/pao3/pa3/a.out
00f74000-00f95000 rw-p 00000000 00:00 0 [heap]
7f0b84000000-7f0b84021000 rw-p 00000000 00:00 0
7f0b84021000-7f0b88000000 ---p 00000000 00:00 0
7f0b8ac00000-7f0b8ac15000 r-xp 00000000 fd:00 15049718 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f0b8ac15000-7f0b8ae14000 ---p 00015000 fd:00 15049718 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f0b8ae14000-7f0b8ae15000 r--p 00014000 fd:00 15049718 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f0b8ae15000-7f0b8ae16000 rw-p 00015000 fd:00 15049718 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f0b8ae16000-7f0b8afda000 r-xp 00000000 fd:00 12593713 /usr/lib64/libc-2.17.so
7f0b8afda000-7f0b8b1d9000 ---p 001c4000 fd:00 12593713 /usr/lib64/libc-2.17.so
7f0b8b1d9000-7f0b8b1dd000 r--p 001c3000 fd:00 12593713 /usr/lib64/libc-2.17.so
7f0b8b1dd000-7f0b8b1df000 rw-p 001c7000 fd:00 12593713 /usr/lib64/libc-2.17.so
7f0b8b1df000-7f0b8b1e4000 rw-p 00000000 00:00 0
7f0b8b1e4000-7f0b8b206000 r-xp 00000000 fd:00 13185028 /usr/lib64/ld-2.17.so
7f0b8b3ca000-7f0b8b3cd000 rw-p 00000000 00:00 0
7f0b8b400000-7f0b8b405000 rw-p 00000000 00:00 0
7f0b8b405000-7f0b8b406000 r--p 00021000 fd:00 13185028 /usr/lib64/ld-2.17.so
7f0b8b406000-7f0b8b407000 rw-p 00022000 fd:00 13185028 /usr/lib64/ld-2.17.so
7f0b8b407000-7f0b8b408000 rw-p 00000000 00:00 0
7ffd41444000-7ffd41465000 rw-p 00000000 00:00 0 [stack]
7ffd414af000-7ffd414b1000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted (core dumped)
【问题讨论】:
-
使用
-g标志开始构建。这将添加调试信息,以便您了解它发生的时间和地点。然后开始缩减你的代码,本质上是创建一个minimal reproducible example。然后使用调试器逐语句逐句执行代码,同时在一张纸上绘制所有对象和指针以跟踪所有内容。如果您仍然无法自己解决问题,那么edit 您的问题将包括您在调试期间发现的内容,并改为显示minimal reproducible example。 -
顺便问一下,你的树有多大?你确定你不会得到太深的递归吗?
-
确切地说,我的树有 199 个节点。我使用 valgrind 和 -g 标志运行编译器。我编辑了我的问题以包含错误消息
-
这不是最小的可重现性,所以无法猜测会出现什么问题,您可以按照内存分配的顺序打印地址,空闲顺序可能会找到一些线索
-
问题是
while (!feof(fp))。另一个可能问题可能是空堆栈。或无效(但非空)left或right树中的指针(从 Valgrind 读取“无效读取”消息是有意义的)。
标签: c memory-management tree preorder