Koz Ross
Koz Ross

Reputation: 3140

Odd behaviour of user-defined min and max functions

I'm writing a tree-like, and as part of that, I need it to have two functions, both of which return a pointer: one to make leaf nodes, and another to make internal nodes. My header file goes as follows:

#ifndef NODE_H
#define NODE_H
#include<stdint.h>

typedef uint32_t Number;

typedef struct Node
{
Number val, height;
struct Node *left, *right, *parent;
} Node;

//makes leaves
Node* make_node (Number);

//makes internal nodes
Node* make_internal (Node*, Node*);

//you'll see why we need these
inline Number num_min(Number, Number);

inline Number num_max(Number, Number);

#endif

The implementation is as follows:

#include "node.h"
#include <stdlib.h>

inline Number num_min(Number a, Number b) {
  return (a < b) ? a : b;
}

inline Number num_max(Number a, Number b) {
  return (a > b) ? a : b;
}

//makes a new leaf node
Node* make_node (Number n) {
  Node* u = calloc(1, sizeof(Node));
  u->val = n;
  u->height = 0;
  return u;
}

//makes a new internal node
Node* make_internal (Node* u, Node* v) {
  Node* uv = calloc(1, sizeof(Node));
  uv->left = u;
  uv->right = v;
  uv->val = num_min(u->val, v->val);
  uv->height = num_max(u->height, v->height) +1;
  u->parent = uv;
  v->parent = uv;
}

Now, make_node works fine (as tested using assert statements), but make_internal doesn't. For example, executing this code causes a coredump:

Node* u = make_node(10);
Node* v = make_node(20);
Node* uv = make_internal(u, v);
assert(uv->val == 10); //this assert fails

When I check the value of uv->val (using printf) at runtime, it turns out to 20 instead of 10! I'm completely confused (and new to C), and would appreciate all possible help.

Upvotes: 0

Views: 56

Answers (2)

Jack
Jack

Reputation: 133597

Try to compile with -Wreturn-type to realize that make_internal doesn't return anything although it is declared to return a Node*:

prism:Dev jack$ gcc -Wreturn-type a.c
a.c: In function ‘make_internal’:
a.c:49: warning: control reaches end of non-void function

Upvotes: 3

adjan
adjan

Reputation: 13674

make_internal is not returning uv. It's result can be anything.

Upvotes: 5

Related Questions