user2502162
user2502162

Reputation:

overloading >> operator giving me run time error C++

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

Answers (1)

Andy Prowl
Andy Prowl

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

Related Questions