1

I am solving Leetcode problem #94 for in-order traversal of a binary tree.

I cannot understand why - when I use &cpy (currently commented) when calling helper() the program works correctly but not when I use &gResult.

int countNode(struct TreeNode* root)
{
    if(root)
        return 1 + countNode(root->left) + countNode(root->right);
    return 0;
}

void helper(struct TreeNode* root, int** res)
{
    if(root)
    {
        helper(root->left, res);
        *((*res)++) = root->val;
        helper(root->right, res);
    }
}

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* inorderTraversal(struct TreeNode* root, int* returnSize){
    int *gResult = NULL; 
    *returnSize = countNode(root);
    gResult = (int*)malloc(((*returnSize)) * sizeof(int));
    memset(gResult, 0, (*returnSize) * sizeof(int));   
    int *cpy = gResult;
//    helper(root, &cpy);
    helper(root, &gResult);
    return gResult;
}

Error Snapshot

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Kingkong Jnr
  • 1,128
  • 4
  • 18
  • 29
  • `&cpy` is a pointer to a pointer to `gResult`. `&gResult` is just a pointer to `gResult`. There's one less level of indirection. – Barmar Aug 28 '22 at 20:09
  • 1
    If the compiler didn't warn you about the type mismatch, you need to increase the warning level. – Barmar Aug 28 '22 at 20:10
  • Isn't gResult and cpy both the same type? Aren't both pointer to an integer? int *cpy = gResult; Isn't this line saying gResult and cpy are the same? – Kingkong Jnr Aug 28 '22 at 20:12
  • `int *cpy` and `int *gPointer` both declare a pointer to an int. `&cpy` would be a pointer to a pointer. Which is what "helper()" needs. – paulsm4 Aug 28 '22 at 20:22
  • **DO NOT post images of code, data, error messages, etc.** - copy or type the text into the question. [ask] – Rob Aug 28 '22 at 20:26
  • It is a bad idea to pass a pointer by reference (or a pointer to the pointer, whatever you want to call it) here. You don't want it to be changed. Rethink your approach. Functions can return values, use it to your advantage. `helper` fills some entries in the array, what if it returned how many? – n. m. could be an AI Aug 28 '22 at 20:30
  • 1
    @KingkongJnr You're right, I misread it as `int *cpy = &gResult;` – Barmar Aug 28 '22 at 22:46

1 Answers1

1

The function helper changes the value of the pointer passed to the function by reference.

    *((*res)++) = root->val;
      ^^^^^^^^

So after calling the function the original pointer will not point to the allocated memory.

Thus using an intermediate pointer like in this code snippet

int *cpy = gResult;
helper(root, &cpy);

leaves the pointer gResult unchanged that points to the dynamically allocated memory and is returned from the function inorderTraversal. And the caller of the function can be able to free the allocated memory successfully using the returned pointer.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thanks. This makes so much sense. Without making that copy, gResult would point to the memory after the last integer and hence freeing that would present an error. So syntactically the code is correct (hence it compiled) but runtime issue. – Kingkong Jnr Aug 28 '22 at 20:59
  • @KingkongJnr You are right.:) – Vlad from Moscow Aug 28 '22 at 21:07