Consider the following example:
#include<iostream>
#include <vector>
using namespace std;
const int UN_INITIALIZED = -1;
struct Node
{
Node *rightNode = nullptr;
int data = UN_INITIALIZED;
};
struct Test {
Test()
{
root.data = 1;
}
void link_nodes()
{
Node n;
cout << "address : " << &n << endl;
n.data = 5;
root.rightNode = &n;
} // n is destroyed? n.rightNode shouldn't be defined?
Node root;
};
int main()
{
Test t;
t.link_nodes();
// out of scope?
cout << t.root.rightNode->data << endl; // This return -1
return 0;
}
When running the following example I get a value of -1 which is the default uninitialized value of Node::data. in link_nodes() shouldn't n be destroyed after the function call ends and calling ->data should give an error or seg fault?
Also when I try creating a different scope in the main function the results tend to be correct :
int main()
{
Node root;
{
Node n;
n.data = 55;
root.rightNode = &n;
} // n died?
cout << root.rightNode->data << endl; //gives 55
return 0;
}
The scope of the variable n is the block scope of the member function link_nodes.
void link_nodes()
{
Node n;
cout << "address : " << &n << endl;
n.data = 5;
root.rightNode = &n;
}
After exiting the function the variable n having automatic storage duration will not be alive. As a result the pointer root.rightNode will be invalid. Dereferencing the pointer results in undefined behavior.
The same problem exists in the second program
Node root;
{
Node n;
n.data = 55;
root.rightNode = &n;
} // n died?
cout << root.rightNode->data << endl;
Again the variable n is not alive after passing the control outside the compound statement where it is defined. So the pointer root.rightNode will be invalid.
Related
I am new to C++. I am trying to implement a stack. I am declaring an arr named variable inside the default constructor.
But when I compile my code I get an error saying
'arr' was not declared in this scope
My code:
#include<iostream>
using std::cout;
using std::endl;
using std::cin;
class Stack
{
private:
int top = -1;
int n = 100;
public:
Stack()
{
int arr[n]; // 100 element stack
}
void push(int element)//push element to the top of the stack
{
if (isFull() == false)
{
// push element
top += 1; //increment top
arr[top] = element;
}
else cout << "\nStack is full! Can't push element\n";
}
void pop()
{
if (isEmpty() == false)
{
top -= 1;//decrement top
}
}
bool isEmpty()
{
if (top == -1)
return true;
else
return false;
}
bool isFull()
{
if (top == n - 1)
return true;
else
return false;
}
int peek(int position)// item at specific location
{
if (position > top)
{
cout << "\nInvalid position\n";
return -1;
}
else
{
return arr[position];
}
}
int count()// number of items
{
return top + 1;
}
void change(int position, int value) // change item at specific location
{
if (position > top)
{
cout << "\nInvalid postion\n";
}
else
{
arr[position] = value;
}
}
void display() // display elements stored
{
if (isEmpty() == false)
{
cout << endl;
for (int i = 0; i < top; i++)
{
cout << arr[i] << endl;
}
}
else
{
cout << endl << "Stack is empty! No elements to display" << endl;
}
}
};
int main()
{
Stack st;
cout << endl;
cout << st.isEmpty();
st.push(10);
cout << endl;
cout << st.isEmpty();
st.display();
return 0;
}
My error:
stack.cpp: In member function 'void Stack::push(int)':
stack.cpp:28:4: error: 'arr' was not declared in this scope
28 | arr[top] = element;
| ^~~
stack.cpp: In member function 'int Stack::peek(int)':
stack.cpp:68:11: error: 'arr' was not declared in this scope
68 | return arr[position];
| ^~~
stack.cpp: In member function 'void Stack::change(int, int)':
stack.cpp:85:4: error: 'arr' was not declared in this scope
85 | arr[position] = value;
| ^~~
stack.cpp: In member function 'void Stack::display()':
stack.cpp:96:11: error: 'arr' was not declared in this scope
96 | cout<<arr[i]<<endl;
| ^~~
I do not understand why this is happening.
Shouldn't be the arr accessable to all member functions?
The
int arr[n]; // 100 element stack
is a local variable that exists only inside the constructor(scope). The other members will not know about this array and that is the reason for the error.
Move the array declaration to the private section and n should be known at compile time
class Stack
{
private:
int top = -1;
static constexpr int n = 100; // n as static constexpr
int arr[n]{ 0 }; // move `arr` here and optionally initlize to `0`
public:
Stack() = default;
// ... rest of the code
};
As a side note, when you do array operations (i.e. like in push member) do a bound check to the passed position.
This is because arr is not a class member, but only a local variable defined in constructor. It vanishes together with constructor scope end.
Start your class like this:
class Stack
{
int top = -1;
static int const n = 100;
int arr[n]; // 100 element stack
public:
Stack() {}
// ...
}
I have tried this piece of code mentioned below, I'm not understanding why *p need to be pass to doOperation() function. Why can't we pass p? What is the difference between the two?
doOperation(*p); // need explanation why derefencing
doOperation(p); // Gives compilation error
int main()
{
int *p = getpointer();
std::cout << "p:" << *p << std::endl;
doOperation(*p); // Why this has to be pass as a pointer when the function parameter as reference
return 0;
}
void doOperation(int &ptr)
{
//std::cout << "ptr:" << ptr << std::endl;
}
int *getpointer()
{
int *ptr = new int[10];
int i;
for (i=0; i <= 10; i++)
{
*(ptr+i) = i;
}
return ptr;
}
You've declared p as an integer pointer. The function doOperation takes an int reference as a parameter. doOperation(*p) means that you're dereferencing the pointer (which points to the first element in the array) and passing it to the function. Also as #dxiv have pointed out, in the function getpointer, the loop initializes 11 elements instead of 10. you can solve this by just changing <= to <.
If you want to pass the pointer by reference instead, the function doOperation can look like this:
void doOperation(int *&ptr)
{
std::cout << "ptr:" << ptr << std::endl;
}
Then you can just pass the pointer as an argument like this:
doOperation(p);
Output:
p:0
ptr:0x2b71550
The code after the changes should look like this:
#include <iostream>
void doOperation(int *&ptr)
{
std::cout << "ptr:" << ptr << std::endl;
}
int *getpointer()
{
int *ptr = new int[10];
int i;
for (i=0; i < 10; i++)
{
*(ptr+i) = i;
}
return ptr;
}
int main()
{
int *p = getpointer();
std::cout << "p:" << *p << std::endl;
doOperation(p);
return 0;
}
I am writing 2 codes for self referential structures :
1st:
struct node
{
int a;
struct node *link;
};
int main()
{
struct node n;
n.a = 5;
cout<< n.a << "\t" ;
cout << n.link ;
return 0;
}
Output : ̀ 5 0x40185b`
2nd:
struct node{
int a;
struct node *link;
};
int main(){
struct node n;
n.a = 5;
cout << n.a << "\t";
cout << *n.link ;
return 0;
}
Output: error:link was not declared in this scope.
Please tell me what is really happening in the code??
Why does a garbage value is thrown??
How can I initialize a self referential structure pointer??
I suppose that's what you want to do:
int main(){
struct node n;
n.a = 5;
n.link = NULL; // initialize the link
cout << n.a << "\t";
cout << n.link;
return 0;
}
*(n.link) will only be valid if n.link points to a valid node object.
And cout << *(n.link); will only be valid if you declare an operator<< for node (cout << n.link; is valid as it outputs the adress, not the value).
For instance, this would work much better:
#include <iostream>
struct node{
int a;
node *link; // Note: no need to prefix with struct
};
std::ostream& operator<<( std::ostream& str, const struct node& n )
{
str << n.a << "\t -> ";
if ( n.link )
str << *n.link;
else
str << "NULL";
return str;
}
int main(){
node n1; // Note: no need to prefix with struct
node n2; // Note: no need to prefix with struct
n1.a = 5;
n1.link = &n2;
n2.a = 6;
n2.link = NULL;
cout << n1;
return 0;
}
It outputs 5 -> 6 -> NULL
I try to write a bidirectional list. I must use overloaded operators([] and +=). [] - access to given node. += - add node to my list. I wrote these methods and it looks ok, but it doesn't work and I have no idea why.
here are core lines of my code:
//********************************************************
CLista::CNode* CLista::operator[](int i_index)
{
int i_help = 0;
CNode* c_result = &c_root;
while(i_help < i_index)
{
c_result = c_result->getNext();
i_help++;
}
return c_result;
}
//*********************************************************
void CLista::operator+=(void* pv_object)
{
if(i_numNodes == 0)
{
c_root = CNode(pv_object);
}
else
{
CNode c_new = CNode(pv_object);
CNode* c_help = this->operator[](i_numNodes - 1);
c_new.setPrevious(c_help);
(*c_help).setNext(&c_new);
}
i_numNodes++;
}
int _tmain(int argc, _TCHAR* argv[])
{
CLista list = CLista();
string s1 = string("first");
void* wsk1 = &s1;
string s2 = string("second");
void* wsk2 = &s2;
string s3 = string("third");
void* wsk3 = &s3;
list += wsk1;
list += wsk2;
list += wsk3;
void* res1 = (*list[0]).getObject();
void* res2 = (*list[1]).getObject();
void* res3 = (*list[2]).getObject();
cout << "res1: " << res1 << endl;
cout << "res2: " << res2 << endl;
cout << "res3: " << res3 << endl;
cout << "wsk1:" << wsk1 << endl;
cout << "wsk2:" << wsk2 << endl;
cout << "wsk3:" << wsk3 << endl;
}
and here is header:
class CLista
{
public:
class CNode
{
public:
CNode(void)
{
pc_next = NULL;
pc_previous = NULL;
}
CNode(void* pv_object)
{
pc_next = NULL;
pc_previous = NULL;
this->pv_object = pv_object;
}
CNode* getNext(){return pc_next;};
CNode* getPrevious(){return pc_previous;};
void* getObject(){return pv_object;};
void setNext(CNode* pc_next);
void setPrevious(CNode* pc_previous);
private:
CNode* pc_next;
CNode* pc_previous;
void* pv_object; // czy to jest dobrze?
};
CNode c_root;
int i_numNodes;
public:
CLista(void);
~CLista(void);
CNode* operator[](int index);
void operator+=(void* object);
};
When I add third element to list and then check it, it is strange problem: addresses of res2 and res3 are the same.
In your operator += function, you create a local CNode called c_new that you link into your linked list. When the scope ends (which happens before the function returns), that local is destructed, leaving the list dangling (pointing at a no longer valid CNode, whose memory is about to be reused for some other local variable, such as the next c_new created on the next call to the function).
Using/accessing an object after it has gone out of scope and been destroyed is undefined behavior, so will generally crash or otherwise misbehave.
I am trying to write a program to create a vector of pointer to objects and then dereference it to print the values it holds.
But the program is aborting due to seg fault .
The segmentation fault is at the line cout << p1->rno << endl; in display( ) function.
Please help me find out the problem.
#include<iostream>
#include<vector>
using namespace std;
class student
{
public:
int rno;
char name[25];
student(int r,char *p):rno(r)
{
//cout << "Con No is" << ++cnt << endl;
strcpy(name,p);
}
static int cnt;
};
void display(vector<student *> &vec)
{
vector<student *> :: iterator p;
student *p1;
for(p = vec.begin( );p != vec.end( );++p);
{
p1 = *p;
cout << p1->rno << endl;
}
}
int student :: cnt = 0;
int main( )
{
vector<student *> vec;
student *p;
int i = 0;
while(i < 10)
{
p = new student(i,"Ganesh");
vec.push_back(p);
i++;
}
display(vec);
system("PAUSE 100");
return 0;
}
You made a typo
for(p = vec.begin( );p != vec.end( );++p);
// ^
Your for loop has empty body.
P.S. I would suggest you to turn on warnings, it can helps you to avoid such typos. For example, clang throws the following warning:
warning: for loop has empty body [-Wempty-body]