It runs ok in my Xcode so can anyone tell me what's the problem?
I tested and the problem is in reallocing space for stack but I don't understand the error..
The test case is [1,null,2,3] so 1 is root, 2 is 1's right child, 3 is 2's left child. The solution should return the array [1,2,3].
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*
**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
struct TreeNode* cercaRoot(struct TreeNode* root, struct TreeNode** stack, int* stackSize){
if (root->left){
*stackSize += 1;
stack = realloc(stack, (*stackSize)*sizeof(struct TreeNode*));
stack[*stackSize-1] = root;
return root->left;
} else if (root->right){
return root->right;
} else{
while(*stackSize){
root = stack[*stackSize-1];
if (root->right) {
*stackSize -= 1;
stack = realloc(stack, (*stackSize)*sizeof(struct TreeNode*));
return root->right;
} else {
*stackSize -= 1;
stack = realloc(stack, (*stackSize)*sizeof(struct TreeNode*));
}
}
return NULL;
}
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
*returnSize = 0;
if (root==NULL) return NULL;
int* array = calloc(1, sizeof(int));
array[0]=root->val;
*returnSize += 1;
int stackSize = 0;
struct TreeNode** stack = calloc(1, sizeof(struct TreeNode*));
root = cercaRoot(root, stack, &stackSize);
while (root){
array = realloc(array, (*returnSize+1)*sizeof(int));
array[*returnSize]=root->val;
*returnSize+=1;
root = cercaRoot(root, stack, &stackSize);
}
//free(stack);
return array;
}
I'm not getting any error with this code
Output is:
ret[0] = 1
ret[1] = 2
ret[2] = 3
#include <stdio.h>
#include <stdlib.h>
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
/*
**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
struct TreeNode* cercaRoot(struct TreeNode* root, struct TreeNode** stack, int* stackSize){
if (root->left){
*stackSize += 1;
stack = realloc(stack, (*stackSize)*sizeof(struct TreeNode*));
stack[*stackSize-1] = root;
return root->left;
} else if (root->right){
return root->right;
} else{
while(*stackSize){
root = stack[*stackSize-1];
if (root->right) {
*stackSize -= 1;
stack = realloc(stack, (*stackSize)*sizeof(struct TreeNode*));
return root->right;
} else {
*stackSize -= 1;
stack = realloc(stack, (*stackSize)*sizeof(struct TreeNode*));
}
}
return NULL;
}
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
*returnSize = 0;
if (root==NULL) return NULL;
int* array = calloc(1, sizeof(int));
array[0]=root->val;
*returnSize += 1;
int stackSize = 0;
struct TreeNode** stack = calloc(1, sizeof(struct TreeNode*));
root = cercaRoot(root, stack, &stackSize);
while (root){
array = realloc(array, (*returnSize+1)*sizeof(int));
array[*returnSize]=root->val;
*returnSize+=1;
root = cercaRoot(root, stack, &stackSize);
}
free(stack);
return array;
}
struct TreeNode* nodeRoot;
int main(int argc, char** argv) {
int stackSize = 0;
int returnSize = 0;
nodeRoot = malloc(sizeof(nodeRoot));
struct TreeNode* nodeLeft = malloc(sizeof(nodeLeft));
struct TreeNode* nodeRight = malloc(sizeof(nodeRight));
nodeRoot->left = nodeLeft;
nodeRoot->right = nodeRight;
nodeRoot->val = 1;
nodeRoot->left = NULL;
nodeRoot->right->val = 2;
nodeRoot->right->left = malloc(sizeof(nodeLeft));
nodeRoot->right->left->val = 3;
int* ret = preorderTraversal(nodeRoot, &returnSize);
if(ret != NULL){
for(int i = 0; i < 3; i++){
printf("ret[i] = %d\n",ret[i]);
}
}
return (EXIT_SUCCESS);
}
If I use sizeof(ret) in the for loop then I get:
ret[0] = 1
ret[1] = 2
ret[2] = 3
ret[3] = 0
ret[4] = 0
ret[5] = 0
ret[6] = 33
ret[7] = 0
Which is expected given the number of valid nodes assigned to the array.
Anyway, the logic seems fine. My first question would be how are you declaring your test case?
Related
Basically I made a create_app() function to allocate 2 nodes in the stack, each having a pointer to an array[max]; undo() pops the last element, and before returning it, it adds it into the REDO node's array. redo() does the opposite, pops the last element in it's array, putting it into Undo's array before returning it. What did I do wrong ?
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define EMPTY_TOS (-1)
typedef struct node *node_ptr;
struct node
{
int arr_size;
int tos;
int *arr_stack;
node_ptr next;
};
typedef node_ptr STACK;
STACK
create_app(int max)
{
STACK UNDO = (STACK) malloc(sizeof(struct node));
STACK REDO = (STACK) malloc(sizeof(struct node));
{
UNDO->arr_stack == (int *) malloc(max * sizeof(int));
REDO->arr_stack == (int *) malloc(max * sizeof(int));
if(UNDO->arr_stack != NULL){printf("Out of space!");}
else
{
UNDO->tos = EMPTY_TOS;
REDO->tos = EMPTY_TOS;
UNDO->arr_size = max;
REDO->arr_size = max;
UNDO->next = REDO;
REDO->next = UNDO;
return UNDO;
}
}
}
int
isEmpty(STACK S)
{
return(S->tos==-1);
}
int
isFull(STACK S)
{
return(S->tos>=S->arr_size-1);
}
void
push(int x, STACK S)
{
if(isFull(S)){printf("Stack full!");}
else
{
S->arr_stack[++S->tos] = x;
}
}
int
undo(STACK S)
{
if(isEmpty(S)){printf("Nothing to undo!");}
else
{
S->next->arr_stack[++S->next->tos] = S->arr_stack[S->tos];
printf("%d",S->arr_stack[S->tos--]);
}
}
int
redo(STACK S)
{
if(isEmpty(S->next)){printf("Nothing to redo!");}
else
{
int temp = S->next->arr_stack[S->next->tos];
push(S->next->arr_stack[S->next->tos], S);
S->next->tos--;
printf("%d",temp);
}
}
int main()
{
STACK app = create_app(5);
push(1,app);
push(2,app);
push(3,app);
undo(app);
undo(app);
redo(app);
redo(app);
/* Expected output: 3223 */
return 0;
}
Some small errors were in your code, like these ones in create_app() which seem like typos.
UNDO->arr_stack == (int *) malloc(max * sizeof(int));
REDO->arr_stack == (int *) malloc(max * sizeof(int));
^
|
if(UNDO->arr_stack != NULL){printf("Out of space!");}
^
|
...
and some int returning functions did not return anything in the else part which gave some warnings.
Here is the modified code, which worked fine for me
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define EMPTY_TOS (-1)
typedef struct node* node_ptr;
struct node
{
int arr_size;
int tos;
int *arr_stack;
node_ptr next;
};
typedef node_ptr STACK;
STACK
create_app(int max)
{
STACK UNDO = (STACK) malloc(sizeof(struct node));
STACK REDO = (STACK) malloc(sizeof(struct node));
{
UNDO->arr_stack = (int *) malloc(max * sizeof(int));
REDO->arr_stack = (int *) malloc(max * sizeof(int));
if(UNDO->arr_stack == NULL){printf("Out of space!");
return NULL;}
else
{
UNDO->tos = EMPTY_TOS;
REDO->tos = EMPTY_TOS;
UNDO->arr_size = max;
REDO->arr_size = max;
UNDO->next = REDO;
REDO->next = UNDO;
return UNDO;
}
}
}
int
isEmpty(STACK S)
{
return (S->tos == -1);
}
int
isFull(STACK S)
{
return (S->tos >= S->arr_size-1);
}
void
push(int x, STACK S)
{
if(isFull(S)){printf("Stack full!");}
else
{
S->arr_stack[++S->tos] = x;
}
}
void
undo(STACK S)
{
if(isEmpty(S)){printf("Nothing to undo!");}
else
{
S->next->arr_stack[++S->next->tos] = S->arr_stack[S->tos];
printf("%d",S->arr_stack[S->tos--]);
}
}
void
redo(STACK S)
{
if(isEmpty(S->next)){printf("Nothing to redo!");}
else
{
int temp = S->next->arr_stack[S->next->tos];
push(S->next->arr_stack[S->next->tos], S);
S->next->tos--;
printf("%d",temp);
}
}
int main()
{
STACK app = create_app(5);
push(1,app);
push(2,app);
push(3,app);
undo(app);
undo(app);
redo(app);
redo(app);
/* Expected output: 3223 */
return 0;
}
Result:
3223
However, always take precaution in deallocating the memory malloced using free().
I'm getting a segmentation fault when trying to access data stored in my TreeNode. Here is the code:
#include <stdio.h>
#include <stdlib.h>
typedef struct NodeTag{
int value;
struct NodeTag *LLink;
struct NodeTag *RLink;
} TreeNode;
void inOrder(TreeNode * n){
if(n->LLink != NULL)
inOrder(n->LLink);
printf("%d ", n->value);
if(n->RLink != NULL)
inOrder(n->RLink);
}
void newNode(TreeNode * n, int v){
n = malloc(sizeof(TreeNode));
n->value = v;
n->LLink = NULL;
n->RLink = NULL;
}
void addValue(TreeNode * r, int value){
if(value < r->value){
if(r->LLink == NULL){
newNode(r->LLink, value);
} else {
addValue(r->LLink, value);
}
} else if (value > r->value) {
if(r->RLink == NULL){
newNode(r->RLink, value);
} else {
addValue(r->RLink, value);
}
}
}
int main(){
TreeNode * root = 0;
newNode(root, 1);
printf("%d\n", root->value); //<--This is where I get the fault
//addValue(root, 3);
//addValue(root, 10);
//addValue(root, 2);
//inOrder(root);
return 0;
}
If anyone can explain to me why I'm getting this error it would be greatly appreciated. I'm a student learning C and I'm not too familiar with pointers and such.
void newNode(TreeNode * n, int v){
n = malloc(sizeof(TreeNode));
n->value = v;
n->LLink = NULL;
n->RLink = NULL;
}
In this code, n is a pointer to a TreeNode struct but if you assign something to n, this is not visible outside of the function as the pointer is passed by value.
void writeToA ( int a ) {
a = 5;
}
int main ( ) {
int x = 10;
writeToA(x)
printf("%d\n", x);
}
What will this code print? It will print 10, not 5. That's because the value of x is passed to the function, not a reference to x. Changing that value within the function will not change the value of x outside the function.
A pointer is also a value, basically it is an int and the int value is a memory address:
void writeToPtr1 ( int * a ) {
int i = 10;
a = &i; // `a` now points to the memory address of i
}
void writeToPtr2 ( int * a ) {
*a = 5; // This doesn't change where `a` points to,
// it writes 5 to the memory address to that `a` points to.
}
int main ( ) {
int x = 10;
int *ptr = &x; // ptr now points to the memory address of x!
writeToPtr1(ptr);
// ptr still points to the memory address of x!
// As not a reference to ptr was passed, the memory
// address of x was passed to the function!
writeToPtr2(ptr);
// ptr still points to the memory address of x!
// But this memory now has the value 5 and not 10 anymore.
}
You need to return the result of the allocation:
TreeNode * newNode ( int v ) {
TreeNode * n = malloc(sizeof(TreeNode));
n->value = v;
n->LLink = NULL;
n->RLink = NULL;
return n;
}
int main ( ) {
TreeNode * root = newNode(1);
printf("%d\n", root->value);
return 0;
}
Or you need to pass a reference to the pointer and then change the value the pointer points to:
void newNode ( TreeNode ** outNode, int v ) {
// TreeNode ** is a pointer to a pointer to a TreeNode!
TreeNode * n = malloc(sizeof(TreeNode));
n->value = v;
n->LLink = NULL;
n->RLink = NULL;
*outNode = n; // Make the pointer point to `n`
}
int main ( ) {
TreeNode * root = NULL;
newNode(&root, 1); // Pass a pointer to root
printf("%d\n", root->value);
return 0;
}
newNode shall either return a pointer to allocated memory or you can send double pointer to the function and allocate memory there.
TreeNode* newNode(int v){
TreeNode *new_node = malloc(sizeof(TreeNode));
n->value = v;
n->LLink = NULL;
n->RLink = NULL;
return new_node
}
or
void newNode(TreeNode ** n, int v){
*n = malloc(sizeof(TreeNode));
(*n)->value = v;
(*n)->LLink = NULL;
(*n)->RLink = NULL;
}
In C arguments are passed by value. Calling newNode(r->LLink, value) will therefore not modify r->LLink.
Consider this simple function:
void Foo(int x)
{
x = x * 2 ;
}
Will calling Foo(n) multiply n by 2 ? No.
You would either need this:
void Foo(int *x)
{
*x = *x * 2 ;
}
and call Foo(&n);
or:
void Foo(int x)
{
return x * 2 ;
}
and call n = Foo(n);
This is my push function
void push(struct Map *map, struct Location location){
struct Node *temp = map->front;
temp->loc = location; //this line causes the error
temp->next = NULL;
if(map->rear == NULL) { // if queue empty
map->front = temp; // First NODE
map->rear = map->front;
}else{// if there is stuff in the queue
map->rear->next = temp;
map->rear = temp;
// Insert End
}
free(temp);
}
and I am getting this error
==2301== Invalid write of size 8
==2301== at 0x401148: push (3146.c:239)
==2301== by 0x400DE7: findEntrance (3146.c:164)
==2301== by 0x400820: main (3146.c:55)
==2301== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==2301==
I am doing a breadth first search on a grid of characters arranged to be a maze. I have been having trouble getting no memory leaks so I have finally found that using malloc helps, but I don't understand why I cannot do this data assignment without a segfault
The alternative is to not free it and have memory leaks, which I don't think is an acceptable solution. Where is my logic wrong?
Below this is the whole program
#include <stdio.h>
#include <stdlib.h>
struct Location;
struct Map;
struct Node;
//function names seem to self describe
void pathFinder(struct Map*);
void findEntrance(struct Map*);
void readInMap(struct Map*);
void printMap(struct Map*);//to screen
/* Q funcs */
void pop(struct Map*);
void push(struct Map*, struct Location);
struct Location {// simple location type
int x;
int y;
};
struct Node {//standard linked list node
struct Location loc;
struct Node *next;
};
struct Map { //variable size encompassing array, and dimension variables
char arr[100][100];
int xLength;//dimensions
int yLength;
int complete;
struct Node *rear;//Q pointers
struct Node *front;
struct Node *currLoc; //temp for BFS
struct Location entrance;
};
int main(){
struct Map map;//the one map to rule them all
map.xLength = 0;//map dimensions
map.yLength = 0;
map.front = NULL; // queue pointers init
map.rear = NULL;
map.currLoc = NULL;
map.entrance.x = 0;
map.entrance.y = 0;
map.complete = 0;
readInMap(&map);
findEntrance(&map);//start off by finding where to start
pathFinder(&map); // problem solver method
printMap(&map);
free(map.front);
free(map.rear);
free(map.currLoc);
return 0;
}
void pathFinder(struct Map *map){
int x;//should be the entrance already pushed from findEntrance
int y;
int done = 0;
struct Location temp;
temp.x = 0;// temp for pushing locations that are adjacent 0's
temp.y = 0;
while(map->front != NULL){
map->currLoc = map->front;//currLoc is just a copy so that we can pop the map location of currLoc from Q
pop(map);// pop so it cant be used twice in this loop
x = map->currLoc->loc.x;
y = map->currLoc->loc.y;
temp.x = 0;
temp.y = 0;
if(map->arr[y][x] == '0'){//protection of 1 values from replacement
map->arr[y][x] = 'X';//replace the array position loc w x
}
if(map->arr[y][x] == '0'){//protection of 1 values from replacement
map->arr[y][x] = 'X';//replace the array position loc w x
printf("test\n");
}
/* find adjacent 0's */
if((y < map->xLength)&&(map->arr[y+1][x] == '0')){
temp.x = x;
temp.y = y+1;
push(map, temp);
}
if((x < map->xLength)&&(map->arr[y][x+1] == '0')){
temp.x = x+1;
temp.y = y;
push(map, temp);
}
if((y > 0)&&(map->arr[y-1][x] == '0')){
temp.x = x;
temp.y = y-1;
push(map, temp);
}
if((x > 0)&&(map->arr[y][x-1] == '0')){
temp.x = x-1;
temp.y = y;
push(map, temp);
}
if((x == 0)||(x == map->xLength)||(y == 0)||(y == map->yLength)){ //then its not on the edge
if((x != map->entrance.x)&&(y != map->entrance.y)){
map->front = NULL;
map->complete++;
}
}
}
}
void findEntrance(struct Map *map){
struct Location entrance;
int done = 0;
int y=0;//index of current row depth
int x=0;//index of current column depth
if (done == 0){
for (x=0;x<=map->xLength;x++){ // top row
if (map->arr[y][x] == '0') {
entrance.x = x;
entrance.y = y;
done = 1;
}
}
}
if (done == 0){
for(y=0;y<=map->yLength;y++){//down the right side
if (map->arr[y][map->xLength] == '0') {
entrance.x = x;
entrance.y = y;
done = 1;
}
}
}
if (done == 0){
for(x;x>=0;x--){//bottom row RtoL
if (map->arr[map->yLength][x] == '0') {
entrance.x = x;
entrance.y = y;
done = 1;
}
}
}
if (done == 0){
for(y;y>=0;y--){//up the left side
if (map->arr[y][0] == '0') {
entrance.x = x;
entrance.y = y;
done = 1;
}
}
}
map->entrance = entrance;
push(map, map->entrance);
}
void readInMap(struct Map *map){
FILE *fptr;
char c;
char file_name[20];
int i,j;
int rows;
int cols;
int x,y;
printf("Size\n");
printf("Rows:");
scanf("%i", &rows);
printf("Columns:");
scanf("%i", &cols);
map->xLength = cols-1; //[y][xLength]
map->yLength = rows-1; //[yLength][x]
for (x=0;x<100;x++){
for (y=0;y<100;y++){
map->arr[x][y] = '1';//whole array is 1
}
}
printf("Type in the name of the file containing the Field\n");
scanf("%s",file_name);
fptr=fopen(file_name, "r");
for (i = 0; i <= map->xLength; i++){
for (j = 0; j <= map->yLength; j++){
c=fgetc(fptr); //handles new line character and spaces
while ( !((c == '1') || (c =='0')) ) {
c=fgetc(fptr);
}
map->arr[i][j] = c;
}
}
printf("\n");
fclose(fptr);
}
void printMap(struct Map *map){
int y;//index of current row depth
int x;//index of current column depth
for (x=0;x<=map->xLength;x++){
for (y=0;y<=map->yLength;y++){//current pos (x,y)
printf("%c", map->arr[x][y]);
}
printf("\n");
}
if(map->complete != 0){
printf("\n An exit to the maze was found that is not the entrance\n");
}else{
printf("\n No exit was found \n");
}
}
void pop(struct Map *map){
if (map->front != NULL){//if not empty
if (map->front == map->rear){
map->rear = NULL;//if the line length is 1, empty it
map->front = NULL;
}else{
map->front = map->front->next;//next in line
}
}else{
map->rear = NULL;//empty out the queue
map->front = NULL;
}
}
void push(struct Map *map, struct Location location){
struct Node *temp = (struct Node*)malloc(sizeof(struct Node));
temp->loc = location;
temp->next = NULL;
if(map->rear == NULL) { // if queue empty
map->front = temp; // First NODE
map->rear = map->front;
}else{// if there is stuff in the queue
map->rear->next = temp;
map->rear = temp;
// Insert End
}
free(temp);
}
When the Map is empty, both front and rear are NULL. So temp->loc is dereferencing a NULL pointer.
You need to malloc the new node and add that to the list. Additionally, you don't want to free here, as that deallocates the memory that you just added to the list.
void push(struct Map *map, struct Location location){
struct Node *temp = malloc(sizeof(struct Node));
temp->loc = location;
temp->next = NULL;
if(map->rear == NULL) { // if queue empty
map->front = temp; // First NODE
map->rear = map->front;
}else{// if there is stuff in the queue
map->rear->next = temp;
map->rear = temp;
// Insert End
}
}
In pop is where you want to deallocate the memory:
void pop(struct Map *map){
struct Node *temp = map->front;
if (map->front != NULL){//if not empty
if (map->front == map->rear){
map->rear = NULL;//if the line length is 1, empty it
map->front = NULL;
}else{
map->front = map->front->next;//next in line
}
free(temp);
}else{
map->rear = NULL;//empty out the queue
map->front = NULL;
}
}
I'm getting a SegFault when passing a function pointer through a couple of structs and I can't figure out what I'm doing wrong. Here's the code:
typedef int (*CompareFuncT)( void *, void * );
typedef void (*DestructFuncT)( void * );
struct AVL
{
void * obj;
struct AVL * parent;
struct AVL * leftChild;
struct AVL * rightChild;
};
typedef struct AVL * AVLPtr;
struct SortedList
{
AVLPtr root;
CompareFuncT comp;
DestructFuncT dest;
};
typedef struct SortedList * SortedListPtr;
SortedListPtr SLCreate(CompareFuncT cf, DestructFuncT df){
SortedListPtr slp = malloc(sizeof(struct SortedList));
if(slp == NULL){
printf("Not enough space for list\n");
return NULL;
}
slp->root = NULL;
slp->comp = cf;
slp->dest = df;
return slp;
}
AVLPtr avl_insert(AVLPtr root, AVLPtr parent, void * obj, int (*compare)( void *, void * )){
int s = 5;
int k = 6;
compare(&s, &k);
if(root == NULL){
root = malloc(sizeof(struct AVL));
if(root == NULL){
printf ("Out of memory - creating AVL node\n");
return NULL;
}
root->obj = obj;
root->parent = parent;
root->leftChild = NULL;
root->rightChild = NULL;
return root;
}
else if (compare(obj, root->obj) < 0){
root->leftChild = avl_insert(root->leftChild, root, obj, compare);
root = balance(root);
}
else if (compare(obj, root->obj) >= 0){
root->rightChild = avl_insert(root->rightChild, root, obj, compare);
root = balance(root);
}
return root;
}
int SLInsert(SortedListPtr list, void * newObj){
list->root = avl_insert(list->root, newObj, list->comp);
if(list->root == NULL)
return 0;
return 1;
}
int compareInts(void *p1, void *p2)
{
int i1 = *(int*)p1;
int i2 = *(int*)p2;
return i1 - i2;
}
void destroyBasicTypeNoAlloc(void *p) {
return;
}
int main(int argc, char **argv) {
int s = 9;
SortedListPtr list = SLCreate(compareInts, destroyBasicTypeNoAlloc);
SLInsert(list, &s);
return 0;
}
There's obviously more parameters going through the function, but this is the propagation of my compare function. I'm getting a SegFault on the compare in avl_insert. I have a feeling I'm just not passing a pointer where I should be, but I just can't find it.
The error is your call of malloc:
SortedListPtr slp = malloc(sizeof(SortedListPtr));
You are allocating the number of bytes that a pointer takes up, which is incorrect. It should be:
SortedListPtr slp = malloc(sizeof(struct SortedList));
I am trying to find the maximum sum leaf to root path in a Binary Tree as in below
http://www.geeksforgeeks.org/find-the-maximum-sum-path-in-a-binary-tree/
1) I am unable to find why the path doesn't get printed in the main()
Is this because of wrong reallocs in the function.?
2) Also is my free correct?
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
/* A tree node structure */
struct node
{
int data;
struct node *left;
struct node *right;
};
// Returns the maximum sum and prints the nodes on max sum path
int maxsumtoleaf(struct node *node,int** path,int &height)
{
// base case
if (node == NULL)
return 0;
printf("\n At node %d,",node->data);
if (node->left==NULL && node->left==NULL) {
*path=(int*)realloc(*path,sizeof(int));
*path[0]=node->data;
height=1;
printf("\n value is %d,",*path[0]);
return node->data;
}
// find the target leaf and maximum sum
int rightheight=0,leftheight=0;
int *path1=NULL,*path2=NULL;
int left=maxsumtoleaf (node->left,&path1,leftheight);
int right=maxsumtoleaf (node->right,&path2,rightheight);
if ( left > right ) {
printf("\nbefore left is");
for(int i=0;i<leftheight;i++)
printf("%d,",path1[i]);
path1=(int*)realloc(path1,sizeof(int)*(leftheight+1));
if ( path1 == NULL ) {
printf("Out of Memory!\n");
return 0;
}
path1[leftheight]=node->data;
height=leftheight+1;
printf("\nafter left %d is ",leftheight);
for(int i=0;i<height;i++)
printf("%d,",path1[i]);
path=&path1;
return left+node->data;
} else {
printf("\nbefore right is");
for(int i=0;i<rightheight;i++)
printf("%d,",path2[i]);
path2=(int*)realloc(path2,sizeof(int)*(rightheight+1));
if ( path2 == NULL ) {
printf("Out of Memory!\n");
return 0;
}
path2[rightheight]=node->data;
height=rightheight+1;
printf("\nafter right is");
for(int i=0;i<height;i++)
printf("%d,",path2[i]);
path=&path2;
return right+node->data;
}
// return maximum sum
}
/* Utility function to create a new Binary Tree node */
struct node* newNode (int data)
{
struct node *temp = new struct node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
/* Driver function to test above functions */
int main()
{
struct node *root = NULL;
/* Constructing tree given in the above figure */
/* (8<--2->-4)<-10->7 */
root = newNode(10);
root->left = newNode(-2);
root->right = newNode(7);
root->left->left = newNode(8);
root->left->right = newNode(-4);
int sum=0;
int** path=NULL;
int height=0;
sum = maxsumtoleaf(root,path,height);
printf ("\nSum of the nodes is %d ,len=%d", sum,height);
printf ("\nPath is ");
for(int i=0;i<height;i++)
printf("%d,",*path[i]);
free(path);
getchar();
return 0;
}
Output:
At node 10,
At node -2,
At node 8,
value is 8,
At node -4,
value is -4,
before left is8,
after left 1 is 8,-2,
At node 7,
value is 7,
before right is7,
after right is7,10,
Sum of the nodes is 17 ,len=2
Path is ---> Breaks at this point in main()
Code is C++ with passing args by reference and using new.
To make C, lots of little fixes including how C "reference" variable are passed (explicitly by address).
You are not doing rellloc() correctly should the allocation fail as you have lost the original pointer.
Always good form to NULL a pointer after freeing it.
#include <stdio.h>
#include <string.h>
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
/* A tree node structure */
struct node {
int data;
struct node *left;
struct node *right;
};
// Returns the maximum sum and prints the nodes on max sum path
int maxsumtoleaf(struct node *node, int** path, int *height) {
// base case
if (node == NULL)
return 0;
printf("\n At node %d,", node->data);
if (node->left == NULL && node->left == NULL) {
*path = (int*) realloc(*path, sizeof(int));
(*path)[0] = node->data;
*height = 1;
printf("\n value is %d,", *path[0]);
return node->data;
}
// find the target leaf and maximum sum
int rightheight = 0, leftheight = 0;
int *path1 = NULL, *path2 = NULL;
int left = maxsumtoleaf(node->left, &path1, &leftheight);
int right = maxsumtoleaf(node->right, &path2, &rightheight);
if (left > right) {
printf("\nbefore left is");
for (int i = 0; i < leftheight; i++)
printf("%d,", path1[i]);
path1 = (int*) realloc(path1, sizeof(int) * (leftheight + 1));
if (path1 == NULL) {
printf("Out of Memory!\n");
return 0;
}
path1[leftheight] = node->data;
*height = leftheight + 1;
printf("\nafter left %d is ", leftheight);
for (int i = 0; i < *height; i++)
printf("%d,", path1[i]);
*path = path1;
return left + node->data;
} else {
printf("\nbefore right is");
for (int i = 0; i < rightheight; i++)
printf("%d,", path2[i]);
path2 = (int*) realloc(path2, sizeof(int) * (rightheight + 1));
if (path2 == NULL) {
printf("Out of Memory!\n");
return 0;
}
path2[rightheight] = node->data;
*height = rightheight + 1;
printf("\nafter right is");
for (int i = 0; i < *height; i++)
printf("%d,", path2[i]);
*path = path2;
return right + node->data;
}
// return maximum sum
}
/* Utility function to create a new Binary Tree node */
struct node* newNode(int data) {
struct node *temp = malloc(sizeof *temp); // new struct node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
/* Driver function to test above functions */
int main() {
struct node *root = NULL;
/* Constructing tree given in the above figure */
/* (8<--2->-4)<-10->7 */
root = newNode(10);
root->left = newNode(-2);
root->right = newNode(7);
root->left->left = newNode(8);
root->left->right = newNode(-4);
int sum = 0;
int* path = NULL;
int height = 0;
sum = maxsumtoleaf(root, &path, &height);
printf("\nSum of the nodes is %d ,len=%d", sum, height);
printf("\nPath is %p ", path);
// return 0;
for (int i = 0; i < height; i++)
printf("%d,", path[i]);
free(path);
path = NULL;
// getchar();
return 0;
}
Preferred realoc() use
// Somehow these are to be updated (initial to NULL and 0)
some_type *current_ptr;
size_t current_element_count; // best too use type size_t
size_t new_element_count = some_function(current_size);
void *new_ptr = realloc(current_ptr, new_element_count * sizeof *current_ptr);
if (new_ptr == NULL && new_element_count > 0) {
Handle_OOM(); // current_ptr is still same & current_element_count elements
return;
}
current_ptr = new_ptr;
current_element_count = new_element_count;
// continue on the happy path