Daniel Martin
Daniel Martin

Reputation: 570

Modifying a pointer passed by reference

I'm not fully understanding this error: when dereferenced the first time, it has the correct value(0). However, upon the second iteration the address of the variable is set to a random address(well not random, it's just adding 3 to the pointers current address instead of adding to to the pointers value).

void constructTree(const unsigned int data[], const unsigned int dataSize, unsigned      int *dataPointer, node* currentNode)
{
//If the pointer is out of bounds, the tree has been built
if (*dataPointer > dataSize) return;
//If the dataPointer is pointing to the id of the current node

if (data[*dataPointer] == currentNode->m_id)
{
    printf("%d, ", currentNode->m_id);
    //Create the left and right nodes
    if (data[*dataPointer + 1] != 0) {
        currentNode->m_left = (node*)malloc(sizeof(node));
        currentNode->m_left->m_id = data[*dataPointer + 1];
        currentNode->m_left->m_left = NULL;
        currentNode->m_left->m_right = NULL;
        currentNode->m_left->m_parent = NULL; 
    }
    if (data[*dataPointer + 2] != 0) {
        currentNode->m_right = (node*)malloc(sizeof(node));
        currentNode->m_right->m_id = data[*dataPointer + 2];
        currentNode->m_right->m_left = NULL;
        currentNode->m_right->m_right = NULL;
        currentNode->m_right->m_parent = NULL;
    }

    printf("%d", *dataPointer);
    constructTree(data, dataSize, &*dataPointer + 3, currentNode->m_left);
    constructTree(data, dataSize, &*dataPointer + 3, currentNode->m_right);

}


}

Calling this function:

    unsigned int dataPointer = 0;
    constructTree(vector, vectorSize, &dataPointer, head);

Upvotes: 1

Views: 59

Answers (3)

Tim B
Tim B

Reputation: 3133

C doesn't actually support passing by reference, perhaps you've just got your terms mixed up? I think the problem is in your line:

constructTree(data, dataSize, &*dataPointer + 3, currentNode->m_right)

If I understand you're thinking, you're expecting this to pass the address of the value addressed by dataPointer plus 3. What it's actually doing is passing the address of the dereferenced pointer, which is the pointer (dataPointer) + 3.

  • dataPointer = pointer
  • *dataPointer = value addressed by dataPointer
  • &*dataPointer = address of the value addressed by dataPointer

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409356

You have actually two problems: The first is because of operator precedence. Both the address-of (&) and dereference (*) operators have higher precedence than the addition operator, so &*dataPointer + 3 is the same as (&*dataPointer) + 3, and as the address-of and dereference operators cancel each other out it's the same as dataPointer + 3.

The second problem is that you can't take the address of an expression, you have to store the expression in a temporary variable and pass the address to that variable. Or if you want to modify the original value then do that and pass the pointer.

So either

int temp = *dataPointer + 3;
constructTree(data, dataSize, &temp, currentNode->m_left);
constructTree(data, dataSize, &temp, currentNode->m_right);

Or

*dataPointer += 3;
constructTree(data, dataSize, dataPointer , currentNode->m_left);
constructTree(data, dataSize, dataPointer , currentNode->m_right);

Upvotes: 0

2501
2501

Reputation: 25753

I'm assuming you don't want to change the original value, so use a temporary variable:

int datatemp = *dataPointer + 3 ;

constructTree(data, dataSize, &datatemp , currentNode->m_left);
constructTree(data, dataSize, &datatemp , currentNode->m_right);

If you do want to change it then change it first and then just pass the pointer:

*dataPointer = *dataPointer + 3 ; 

constructTree(data, dataSize, dataPointer , currentNode->m_left);
constructTree(data, dataSize, dataPointer , currentNode->m_right);

Upvotes: 2

Related Questions