-6
#include"iostream"
using namespace std;

class xxx
{
    public:
        char **a;
        xxx();
        ~xxx();
};
xxx :: xxx()
{
    a=new char*;
    *a="10";
    cout<<endl<<*a;    // works fine
    cout<<"Enter name:";
    cin>>*a;          // segmentation fault??
}
xxx :: ~xxx()
{
   delete a;
}

main()
{
   xxx x;
    cout<<*x.a;
}

why can't I change the name field using cin ? When i am calling a constructor it is assigning the value to the variable but While editing it is showing the following error: program has stopped working. same problem arises for method.What am I missing.

3 Answers3

1

Within the constructor of xxx, *a is initialised so it points at (the first character of) a string literal.

The statement cin >> *a then attempts to modify the string literal. That gives undefined behaviour. The symptom you are describing is one possible outcome of undefined behaviour.

A simpler example, without the obfuscating details of class xxx would be

 #include <iostream>

 int main()
 {
     char **a = new char *;
     *a = "10";
     std::cout << std::endl << *a;    // works fine
     std::cout << "Enter name:";
     std::cin >> *a;          //  undefined behaviour here
 }

Although, as with any form of undefined behaviour, a particular outcome/symptom is not guaranteed.

You might try turning up warning levels for your compiler, and the result will probably be warnings about a suspicious conversion in the statement *a = "10" (e.g. converting something const to not const). Most modern C++ compilers (and quite a few older ones) are configured to NOT warn about such things by default, but can be configured to issue such warnings. Turning up compiler warnings, and taking heed of them, is helpful in reducing such types of undefined behaviour.

Peter
  • 35,646
  • 4
  • 32
  • 74
1

The problem with your code is quite simple, for that matter. In your constructor:

xxx :: xxx()
{
    a=new char*;
    *a="10";
    cout<<endl<<*a;    // works fine
    cout<<"Enter name:";
    cin>>*a;          // segmentation fault??
}

You are trying to read into an already initialized string literal, which is then causing Undefined Behavior. If you want to do something like this, and you are using C++, you should probably switch to std::string, which will make your code a lot simpler without dealing with raw string literals and pointers, as follows:

#include <iostream>
#include <string>

class xxx
{
    public:
        std::string a;
        xxx();
        ~xxx();
};
xxx :: xxx()
{
    a = "10";
    std::cout << std::endl << a;
    std::cout << "Enter name:";
    std::cin >> a;
}

int main()
{
    xxx x;
    std::cout<< x.a;
}

In this example, code such as a=new char*; and delete a; are removed along with the destructor itself. Other changes I made include changing your code to not using using namespace std; (Read why it is considered bad practice) and using the return type of int for main(). Additionally, I included the <string> library as well for std::string. Finally, as another recommendation, since std::cin will only read the first word passed to it and ignore the rest, if you want to read a full name then you can use getline() as follows:

//std::cin >> a; becomes...
getline(std::cin, a);
Arnav Borborah
  • 11,357
  • 8
  • 43
  • 88
0

Issue in your code can be minimized to this snippet of invalid code:

 char *p = "foobar"; // should not compile, but would on many compilers due to backward compatibility
 p[0] = 'F';

issue is you are trying to modify memory where string literal resides which is UB.

Slava
  • 43,454
  • 1
  • 47
  • 90