c - Function to turn a Binary Tree into the sums of all nodes below each node; segmentation fault if I don't create a new binary tree -


i want create function sum nodes below node including own value, this

  3                       6  / \                     / \ 1   2  turn  1   2 

link exercise in question: https://codeboard.io/projects/16280

here's defenition of abin , call function:

typedef struct nodo {     int valor;     struct nodo *esq, *dir; } *abin;  abin somasaca (abin a); 

this version works, though don't because creates new binary tree:

int getsums(abin a){     int esq, dir;     if(a == null) return 0;     esq = getsums(a->esq);     dir = getsums(a->dir);     return(a->valor + esq + dir);  }  abin somasaca (abin a) {     abin b, *res;     res = &b;      if(a!=null){         b = newabin(getsums(a), null,null);         b->esq= somasaca(a->esq);         b->dir= somasaca(a->dir);     }     if(a==null) b=null;     return *res; } 

and version gives me segmentation fault:

abin somasaca (abin a) {     if(a == null) return null;     a->valor = getsums(a);     a->esq = somasaca(a->esq);     a->dir = (somasaca(a->dir));     return a; } 

the thing is, if put a->valor = getsums(a); in middle don't segfault (but wrong values if height of tree higher 2). causing segmentation fault , why can't without creating new bin tree? thanks.

it nuisance when have create mcve fragments of program. however, it's doable — it's pain, doable.

here's variation on code. of 115 lines shown, 35 wrote in question — roughly. so, had create twice code create semi-plausible mcve.

#include <assert.h> #include <stdio.h> #include <stdlib.h>  typedef struct abin_s *abin; struct abin_s {     int valor;     abin esq;     abin dir; };  abin somasaca_ok(abin a); int getsums(abin a); abin somasaca(abin a);  static abin newabin(int valor, abin esq, abin dir) {     abin ab = malloc(sizeof(*ab));     if (ab == 0)     {         fprintf(stderr, "failed malloc %zu bytes\n", sizeof(*ab));         exit(exit_failure);     }     ab->valor = valor;     ab->esq = esq;     ab->dir = dir;     return ab; }  int getsums(abin a) {     if (a == null)         return 0;     int esq = getsums(a->esq);     int dir = getsums(a->dir);     return(a->valor + esq + dir); }  abin somasaca_ok(abin a) {     abin b, *res;     res = &b;      if (a != null)     {         b = newabin(getsums(a), null, null);         b->esq = somasaca_ok(a->esq);         b->dir = somasaca_ok(a->dir);     }     if (a == null)         b = null;     return *res; }  abin somasaca(abin a) {   // remove unused b     if (a != null)     {         a->valor = getsums(a);         a->esq = somasaca(a->esq);         a->dir = somasaca(a->dir);     }     return a; }  static void print_postorder(abin node) {     if (node != 0)     {         print_postorder(node->esq);         print_postorder(node->dir);         printf("valor = %d\n", node->valor);     } }  static void print_tree(const char *tag, abin node) {     printf("tree: %s\n", tag);     print_postorder(node); }  static void free_tree(abin node) {     if (node != 0)     {         free_tree(node->esq);         free_tree(node->dir);         free(node);     } }  int main(void) {     abin root = newabin(3, 0, 0);     abin esq = newabin(1, 0, 0);     abin dir = newabin(2, 0, 0);     root->esq = esq;     root->dir = dir;      print_tree("before", root);      abin eval = somasaca(root);     assert(eval == root);      print_tree("after", root);      eval = somasaca_ok(root);     assert(eval != root);      print_tree("second time", root);      free(root);     free(esq);     free(dir);     free_tree(eval); } 

i created somasaca_ok() working function, marginally cleaning up. somasaca() 'non-working' function, cleaned up. don't think changed functionality of either. note tree building code doesn't attempt use function build — you've not shown such function. creates 3 nodes , links them manually.

the code compiles cleanly under gcc 6.1.0 on mac os x 10.11.5 command line:

$ gcc -o3 -g -std=c11 -wall -wextra -wmissing-prototypes -wstrict-prototypes \ >     -wold-style-definition -werror abin.c -o abin $ 

when run under valgrind, gets clean bill of health.

$ ./abin tree: before valor = 1 valor = 2 valor = 3 tree: after valor = 1 valor = 2 valor = 6 tree: second time valor = 1 valor = 2 valor = 6 $ 

on basis of see, second lot of code, 1 claim fails, works correctly, 1 claim succeeds doesn't addition (the last valor should 9 on second time).

i'm bit dubious way functions work. i'd expect somasaca() evaluating sub-trees before summing modified trees. works side-effect of minimal tree. maybe should using:

abin somasaca(abin a) {     if (a != null)     {         a->esq = somasaca(a->esq);         a->dir = somasaca(a->dir);         a->valor = getsums(a);     }     return a; } 

i'm not convinced needs return value, either, collateral changes, use:

void somasaca(abin a) {     if (a != null)     {         somasaca(a->esq);         somasaca(a->dir);         a->valor = getsums(a);     } } 

extending testing more extensive trees left exercise correct tree-creation function code.