Reputation:
Can anyone help me. Below is the code which I'm trying to execute. There is no compile time error but the program crashes when the control goes to string copy statement. I'm trying to fix it for almost one hour, but still not succeeded.
#include <iostream>
using namespace std;
class test
{
private:
char* name;
friend istream& operator >>(istream&, test&);
};
istream& operator >> (istream& is, test& t)
{
char c[20];
cout << "enter something";
is >> c;
strcpy(t.name, c);
return is;
}
int main()
{
test obj;
cin >> obj;
}
Upvotes: 1
Views: 886
Reputation: 126432
The name
pointer is uninitialized by the time you are invoking strcpy
, which gives your program undefined behavior.
To avoid this kind of problem, use std::string
rather than C strings. More concretely, redefine your class this way:
#include <string> // Needed for std::string
class test
{
private:
std::string name;
friend istream& operator >>(istream&, test&);
};
To make your program compile, you could then adapt your overload of operator >>
this way:
istream& operator >> (istream& is, test& t)
{
cout << "enter something";
is >> t.name;
return is;
}
Notice, however, that you should not prompt the user for information inside your extraction operator (i.e. inside the overload of operator >>
). The insertion operator is only supposed to extract an object of type test
from an input stream.
Thus, to provide a complete example:
#include <iostream>
#include <string>
class test
{
private:
std::string name;
friend std::istream& operator >>(std::istream&, test&);
};
std::istream& operator >> (std::istream& is, test& t)
{
is >> t.name;
return is;
}
int main()
{
test obj;
std::cout << "enter something: ";
std::cin >> obj;
}
Also avoid using
directives such as:
using namespace std;
Especially if at namespace scope and especially if in a header (not your case, but still) - they tend to cause name clashes with entities that live in the std
namespace.
EDIT:
Since it seems you are not allowed to use std::string
, only the first sentence of the original answer remains valid - and the part about where you should be asking input from the user, perhaps.
So this is what you can write for assigning t.name
a copy of the string input by the user:
t.name = strdup(c);
You will need to include the <cstring>
standard header for strdup()
:
#include <cstring>
I would also suggest to initialize the name
pointer to null in the constructor of the test
class - it doesn't get initialized by the implicitly-generated default constructor:
class test
{
test() : name(nullptr) { } // Use NULL instead of nullptr in C++03
private:
char* name;
friend istream& operator >> (istream&, test&);
};
So in a complete program:
#include <iostream>
#include <cstring>
class test
{
public:
test() : name(nullptr) { }
private:
char* name;
friend std::istream& operator >>(std::istream&, test&);
};
std::istream& operator >> (std::istream& is, test& t)
{
char c[20];
is >> c;
t.name = strdup(c);
return is;
}
int main()
{
test obj;
std::cout << "enter something: ";
std::cin >> obj;
}
Upvotes: 7