Reputation: 298
In order to complete my homework I had to implement a list in C++, thus I defined a structure:
struct Node {
int value;
Node * next;
Node * operator [] (int index)//to get the indexed node like in an array
{
Node *current = this;
for (int i = 0; i<index; i++)
{
if (current==NULL) return NULL;
current = current->next;
}
return current;
}
};
When I used it with actual structures, it worked fine:
Node v1, v2, v3;
v1.next = &v2;
v2.next = &v3;
v3.value = 4;
v3.next = NULL;
cout<<v1[2]->value<<endl;//4
cout<<v2[1]->value<<endl;//4
cout<<v3[0]->value<<endl;//4; works just as planned
cout<<v3[1]->value<<endl;//Segmentation fault
But when i tried to use it with pointers, the things got messed up:
Node *v4, *v5, *v6;
v4 = new Node;
v5 = new Node;
v6 = new Node;
v4->next = v5;
v4->value = 44;
v5->next = v6;
v5->value = 45;
v6->next = NULL;
v6->value = 4646;
//cout cout<<v4[0]->value<<endl; compiler says it's not a pointer
cout<<v4[0].value<<endl;//44
cout<<v4[1].value<<endl;//1851014134
cout<<v4[2].value<<endl;//45
cout<<v4[3].value<<endl;//1851014134
cout<<v4[4].value<<endl;//4646
cout<<v4[5].value<<endl;//1985297391;no segmentation fault
cout<<v6[1].value<<endl;//1985297391;no segmentation fault even though the next was NULL
delete v4;
delete v5;
delete v6;
Though it is possible to work with function, I've got some questions:
I'd be very thankful if someone explained me these moments or gave me the sources I could learn from
Upvotes: 4
Views: 123
Reputation: 913
By doing this
v4 = new Node;
cout<<v4[0].value<<endl;//44
cout<<v4[1].value<<endl;//1851014134
cout<<v4[2].value<<endl;//45
cout<<v4[3].value<<endl;//1851014134
cout<<v4[4].value<<endl;//4646
cout<<v4[5].value<<endl;//1985297391;no segmentation fault
You are not calling operator[] of struct Node, you are making pointer dereferencing, v4[1]
is equal to ++v4; *v4;
So this code is causing unpredicted behavior, because you are dereferencing some garbage.
To make it work as you want, you need to change it to:
cout<<v4->operator[](0).value<<endl;
cout<<v4->operator[](1).value<<endl;
cout<<v4->operator[](2).value<<endl;
...
Upvotes: 1
Reputation: 302643
That's because v4[0]
(and the rest) aren't actually calling your Node::operator[]
. That's because v4
isn't a Node
, it's a Node*
, and pointers have a builtin meaning behind operator[]
: v4[i] == *(v4 + i)
(that is, we're just indexing into that "array"). So when you write something like v4[3]
, that isn't calling operator[](3)
... it's instead giving you back a Node
three Node
s after v4
in memory somewhere, which is basically just garbage.
To get what you want to happen, you'd have to dereference the pointers first:
(*v4)[0]
(*v6)[1]
// etc
Upvotes: 5