0

I have a partial implementation of a binary tree that doesn't work properly. I believe I am missing fundamental knowledge about struct memory management in objective-c but not sure what it is(besides malloc). When I try to create a new tree node based on a struct I get

Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)

which led me to believe I didn't create a memory location for this struct pointer. What is the proper way of doing this in Objective-C? (Code in below)

Thank you for taking the time to respond. The code seems correct from the logic perspective so not sure what the issue is here.

EDIT I've modified the source code based on @trungduc 's response. But now I am getting a stack overflow in the printDescription method issue:

Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffeef3fffe8) // on line [self printDescription:root.left];

PS. I did see this question but didn't help. I also saw this repo but I am not sure happy with some of the implementation details so I ended up not following it. Does anyone know any good guides/tutorials on how to do trees and graphs in Objective-C?

Main.m

#import <Foundation/Foundation.h>

// BSTNode is an Objective-C class
@interface BSTNode : NSObject

@property (nonatomic, assign) int data;
@property (nonatomic, strong) BSTNode *left;
@property (nonatomic, strong) BSTNode *right;

@end

@implementation BSTNode

@end

@interface BST: NSObject

- (BSTNode *)insertNode:(BSTNode *)root withData:(int)data;
- (void)printDescription:(BSTNode *)root;

@end

@implementation BST

- (BSTNode *)initializeTreeNode {
    // By default, |data| is 0, |left| is nil, |right| is nil
    return [[BSTNode alloc] init];
}

- (BSTNode *)insertNode:(BSTNode *)root withData:(int)data {
    if(!root) {
        root = [self initializeTreeNode];
        root.data = data;
    } else if (root.data >= data) {
        root.left = [self insertNode:root.left withData:data];
    } else {
        root.right = [self insertNode:root.right withData:data];
    }

    return root;
}

- (void)printDescription:(BSTNode *)root {
    // in order left - root - right
    [self printDescription:root.left];
    NSLog(@"%d",root.data);
    [self printDescription:root.right];
}

@end

and inside the main method:

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        BST *bst = [[BST alloc] init];;
        BSTNode *root = [[BSTNode alloc]init];
        [bst insertNode:root withData:20];
        [bst insertNode:root withData:15];
        [bst insertNode:root withData:25];
        [bst printDescription:root];
   }
    return 0;
}
Matt
  • 674
  • 11
  • 25

1 Answers1

1

You got crash because you called node->data while node is NULL.

In this case, I suggest to define BSTNode as an Objective-C class. You can try my code below.

// BSTNode is an Objective-C class
@interface BSTNode : NSObject

@property (nonatomic, assign) int data;
@property (nonatomic, strong) BSTNode *left;
@property (nonatomic, strong) BSTNode *right;

@end

@implementation BSTNode

@end

@interface BST: NSObject

- (BSTNode *)insertNode:(BSTNode *)root withData:(int)data;
- (void)printDescription:(BSTNode *)root;

@end

@implementation BST

- (BSTNode *)initializeTreeNode {
  // By default, |data| is 0, |left| is nil, |right| is nil
  return [[BSTNode alloc] init];
}

- (BSTNode *)insertNode:(BSTNode *)root withData:(int)data {
  if(!root) {
    root = [self initializeTreeNode];
    root.data = data;
  } else if (root.data >= data) {
    root.left = [self insertNode:root.left withData:data];
  } else {
    root.right = [self insertNode:root.right withData:data];
  }

  return root;
}

- (void)printDescription:(BSTNode *)root {
  if (!root) {
      return;
  }

  // in order left - root - right
  [self printDescription:root.left];
  NSLog(@"%d",root.data);
  [self printDescription:root.right];
}

@end
trungduc
  • 11,926
  • 4
  • 31
  • 55
  • thanks for the reply. Although your answer is clean and easy to understand I am getting a stack overflow in the print description `[self printDescription:root.left];` any idea why would that be? I updated the question. – Matt Aug 03 '18 at 16:16
  • @Matt I have updated `printDescription`, you can check and try again. – trungduc Aug 03 '18 at 16:27
  • @Matt Take a look at https://github.com/EvgenyKarkan/EKAlgorithms/tree/master/EKAlgorithms/Data%20Structures if you need a good sample – trungduc Aug 03 '18 at 16:30
  • I was actually following that. Although it was useful for the most part, I didn't like how he used `NSComparisonResult` `selector` on insert and find methods for the BST. Do you have any alternative suggestions for BST and Graph examples? – Matt Aug 03 '18 at 16:33
  • I checked but I didn't find anything related to `NSComparisonResult` in `EKBTree.m` file – trungduc Aug 03 '18 at 17:37
  • checkout `EKBSTree.m` the `EKBTree.m` implementation was fine. – Matt Aug 03 '18 at 18:24