前提・実現したいこと
入力された算術式を二分木と捉えて、右回転・左回転を使って分配法則を行って展開する関数を作成しています。((x+9)(y+8))であれば((((xy)+(9y))+(x8))+(98))に、(7((p+(q+r))(x+y)))は(((((((7p)x)+((7q)x))+((7r)x))+((7p)y))+((7q)y))+((7r)y))という形になればいいです。
((x+9)(y+8))は正しく表示されるのですが、(7*((p+(q+r))(x+y)))は正しく表示されず、計算結果も(((((((((77)*p)*x)y)+((((77)*q)*x)y))+((((77)*r)*x)y))+((((77)*p)*x)y))+((((77)*q)*x)y))+((((77)*r)*x)*y))となり、計算結果も294と正解の42と全く違う値になってしまいます。
発生している問題・エラーメッセージ
C
1(7*((p+(q+r))*(x+y))) 2show: (7*((p+(q+r))*(x+y))) 3eval: 42 4dist: (((7*(7*((p*x)*y)))+((7*(7*((q*x)*y)))+(7*(7*((r*x)*y)))))+((7*(7*((p*x)*y)))+((7*(7*((q*x)*y)))+(7*(7*((r*x)*y)))))) 5assoc: (((((((((7*7)*p)*x)*y)+((((7*7)*q)*x)*y))+((((7*7)*r)*x)*y))+((((7*7)*p)*x)*y))+((((7*7)*q)*x)*y))+((((7*7)*r)*x)*y)) 6eval: 294 7 8*** Error in `./ex3': double free or corruption (fasttop): 0x0000000001c31290 *** 9======= Backtrace: ========= 10/lib64/libc.so.6(+0x7c619)[0x7f9273d1f619] 11./ex3[0x400a84] 12./ex3[0x400a68] 13./ex3[0x400a78] 14./ex3[0x400a68] 15./ex3[0x400a68] 16./ex3[0x400b74] 17./ex3[0x4012c8] 18/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f9273cc4c05] 19./ex3[0x4006c9] 20======= Memory map: ======== 2100400000-00402000 r-xp 00000000 00:28 9045122 /exports/home/j418828/centos7/AdvProg/T6/week02/ex3 2200601000-00602000 r--p 00001000 00:28 9045122 /exports/home/j418828/centos7/AdvProg/T6/week02/ex3 2300602000-00603000 rw-p 00002000 00:28 9045122 /exports/home/j418828/centos7/AdvProg/T6/week02/ex3 2401c31000-01c52000 rw-p 00000000 00:00 0 [heap] 257f926c000000-7f926c021000 rw-p 00000000 00:00 0 267f926c021000-7f9270000000 ---p 00000000 00:00 0 277f9273a8d000-7f9273aa2000 r-xp 00000000 08:01 2365672 /usr/lib64/libgcc_s-4.8.5-20150702.so.1 287f9273aa2000-7f9273ca1000 ---p 00015000 08:01 2365672 /usr/lib64/libgcc_s-4.8.5-20150702.so.1 297f9273ca1000-7f9273ca2000 r--p 00014000 08:01 2365672 /usr/lib64/libgcc_s-4.8.5-20150702.so.1 307f9273ca2000-7f9273ca3000 rw-p 00015000 08:01 2365672 /usr/lib64/libgcc_s-4.8.5-20150702.so.1 317f9273ca3000-7f9273e5b000 r-xp 00000000 08:01 2361504 /usr/lib64/libc-2.17.so 327f9273e5b000-7f927405b000 ---p 001b8000 08:01 2361504 /usr/lib64/libc-2.17.so 337f927405b000-7f927405f000 r--p 001b8000 08:01 2361504 /usr/lib64/libc-2.17.so 347f927405f000-7f9274061000 rw-p 001bc000 08:01 2361504 /usr/lib64/libc-2.17.so 357f9274061000-7f9274066000 rw-p 00000000 00:00 0 367f9274066000-7f9274087000 r-xp 00000000 08:01 2361497 /usr/lib64/ld-2.17.so 377f9274269000-7f927426c000 rw-p 00000000 00:00 0 387f9274283000-7f9274287000 rw-p 00000000 00:00 0 397f9274287000-7f9274288000 r--p 00021000 08:01 2361497 /usr/lib64/ld-2.17.so 407f9274288000-7f9274289000 rw-p 00022000 08:01 2361497 /usr/lib64/ld-2.17.so 417f9274289000-7f927428a000 rw-p 00000000 00:00 0 427ffdda0c5000-7ffdda0e6000 rw-p 00000000 00:00 0 [stack] 437ffdda11b000-7ffdda11d000 r-xp 00000000 00:00 0 [vdso] 44ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] 45Abort (core dumped)
該当のソースコード
C
1void dist_prod_exp_sub(Exp *ep) { 2 if((*ep)->node == '*' && (*ep)->left->node != '+' && (*ep)->right->node == '+'){ 3 rotate_left_exp(ep); 4 (*ep)->right = make2_exp('*', ((*ep)->left)->left, (*ep)->right); 5 dist_prod_exp(&(*ep)); 6 } 7 else if((*ep)->node == '*' && (*ep)->left->node == '+' && (*ep)->right->node != '+') { 8 rotate_right_exp(ep); 9 (*ep)->left = make2_exp('*', (*ep)->left, ((*ep)->right)->right); 10 dist_prod_exp(&(*ep)); 11 } 12 else if((*ep)->node == '*' && (*ep)->left->node == '+' && (*ep)->right->node == '+') { 13 rotate_left_exp(ep); 14 (*ep)->right = make2_exp('*',((*ep)->left)->left, (*ep)->right); 15 rotate_right_exp(&((*ep)->left)); 16 ((*ep)->left)->left = make2_exp('*', ((*ep)->left)->left, (((*ep)->left)->right)->right); 17 rotate_right_exp(&((*ep)->right)); 18 ((*ep)->right)->left = make2_exp('*', ((*ep)->right)->left, ((*ep)->right)->right->right); 19 dist_prod_exp(&(*ep)); 20 } 21 if((*ep)->left != NULL) 22 dist_prod_exp(&((*ep)->left)); 23 if((*ep)->right != NULL) 24 dist_prod_exp(&((*ep)->right)); 25} 26 27void dist_prod_exp(Exp *ep) { 28 dist_prod_exp_sub(ep); 29 dist_prod_exp_sub(ep); 30}
試したこと
((x+9)*(y+8))などを入力すると、正しく展開はされていますが、二回目を入力すると上と同じようなエラー文が表示されます。
補足情報
このプログラムの演算子は、和と積のみです。
出力には、showは入力された算術式をそのまま表示、evalは計算結果を表示(アルファベットは1として計算)、distは分配法則を使って展開した式を表示、assocはdistで表示された式の括弧をすべて左にくくりなした式を表示しています。
Exp型は、2分木の節を格納するためのデータ構造で、下の構造体と同じ形です。
C
1typedef struct _tree { 2 char node; /* 節のデータ (1文字) */ 3 struct _tree *left; /* 左の子へのポインタ */ 4 struct _tree *right; /* 右の子へのポインタ */ 5} Tree;
rotate_left_exp、rotate_right_expはそれぞれ二分木を左回転・右回転する関数です。
make2_expは、括弧の中の引数で二分木を生成する関数で、左から根となる演算子、左の子の値、右の子の値です。
周りの人に聞いてもあまり分かってないため、ここで初めて質問させていただきます。長々とすみません、よろしくお願いします。
回答2件
あなたの回答
tips
プレビュー