We help IT Professionals succeed at work.

string in c++ is not working properly

Naman Goel
Naman Goel asked
on
379 Views
Last Modified: 2010-05-18
#include<iostream.h>
#include<string.h>
class string
{
char *s;
public:
string()
{
strcpy(s,"c++");
}
string(char * s1)
{
strcpy(s,s1);
}
void display()
{
cout<<endl<<s;
}
};



void main()
{
string s1,s2("language");
s1.display();
s2.display();
}

it gaves output:-

c++





Comment
Watch Question

efn

Commented:
A char* variable is a pointer.  Declaring one does not automatically give you any characters for it to address.  They have to be allocated separately.  The calls to strcpy copy strings to whatever memory s addresses and s is not initialized.  If you want a string variable to contain some characters, you need to allocate some storage for them somehow.  As a starting point, you could try declaring s as a character array instead of a pointer, for example:

char s[500];

--efn
Hmm yes ... how can you get an output with this code ? (i.e. how come it didn't crash before)
efn

Commented:
You can avoid a crash and possibly even get an output if you get lucky with the garbage value of s.
Points to be remebered while using POINTERS

:: During definition of the pointer always initialize it with some value or else with NULL.
:: before using any memoey area allocate it first.

In the program given by you, you haven't allocated any memory for your *s member variable. And you are using that place for storing some string. In many compiler it will crash if not then it will give you unexpected results... So before using s first allocate some memory for it.......


Dennis
use this code instead:

// Q_20885998.cpp : Defines the entry point for the console application.
//

#include<iostream>
#include<string.h>
class string
{
char *s;
void initstring(size_t sz)
{
      s = new char[sz];
}
public:
string()
{
initstring(strlen("c++"));
strcpy(s,"c++");
}
string(char * s1)
{
initstring(strlen(s1));
strcpy(s,s1);
}
~string()
{
delete [] s;
}
void display()
{
      std::cout<<std::endl<<s;
}
};



void main()
{
string s1,s2("language");
s1.display();
s2.display();
}

CERTIFIED EXPERT

Commented:
avoid putting the display method in the string class itself as it will make the class difficult to use in other programs such as GUI applications etc. A word of advice, if you are writing this class as an academic excersise then fine but if you are trying to create a string class for a real project then i suggest you re-use the stl::string class or the MFCs CString - it will save you alot of time and effort

class my_string
{
protected:
  char *m_data;
  int m_len;
private:
  my_string()
  {
    m_len = 0;
    m_data = NULL;
  }
  my_string(char *str)
  {
     m_len = strlen(m_data);
     m_data = (char*)malloc(m_len);
     strcpy(m_data,str);
  }
  ~my_string()
  {
      if(m_data != NULL) free(m_data);
  }
  char *c_str()
  {
     return m_data;
  }
};

void main()
{
  my_string str("C++");
  cout<<str.c_str()<<endl;
}
CERTIFIED EXPERT

Commented:
sorry - change private to public
Naman GoelPrincipal Software engineer
CERTIFIED EXPERT

Author

Commented:

hello all experts
#include<iostream.h>
#include<string.h>
class string
{
char *s;
public:
string()
{
strcpy(s,"c++");
}
string(char * s1)
{
strcpy(s,s1);
}
void display()
{
cout<<endl<<s;
}
};


/*-----------------------------------------------
void main()
{
/*when we use another object for this purpose*/
string s1,s,s2("language");
s1.display();
s2.display();
}

it gaves output:-

c++
language

it same output when we are using code like this in main function:-

void main()
{

string s1;
s1.display();
string s2("language");
s2.display();
}

why????

Didn't you read the comments before?

You still don't allocate any storage to the pointer s. So you are simply lucky if your program doesn't crash.

class string
{
char *s;
public:
string()
{
s = new char[4];
strcpy(s,"c++");
}
string(char * s1)
{
s = new char[strlen(s1)+1];
strcpy(s,s1);
}
void display()
{
cout<<endl<<s;
}
};

Sorry, I forgot about /0 char at the end of string, so you should use following code in initstring
void initstring(size_t sz)
{
     s = new char[sz+1];
}

Commented:
Hi naman_goel,

   The problem with your code was that, for the char pointer s, the memory was not allocated. If you allocate memory in your constructor and add a destructor to deallocate, your program will work fine.
   So, I have modified your code as little as possible and have posted it here, so that it will work for you:

#include<iostream>
#include<string>
using namespace std;

class my_string
{
private:
        char *s;
public:
        my_string()
        {
                s = new char [32];
                strcpy(s,"c++");
        }
        my_string(char * s1)
        {
                s = new char [32];
                strcpy(s,s1);
        }
        void display()
        {
                cout<<endl<<s<<endl;
        }
        ~my_string()
        {
                delete [] s;
        }
};

int main()
{
        my_string s1,s2("language");
        s1.display();
        s2.display();

        return 0;
}

Hope you can take on from here and refine it, in the way C++ standard demands!

-ssnkumar
Naman GoelPrincipal Software engineer
CERTIFIED EXPERT

Author

Commented:
why we have to allocate memory when this is working when we declare first object and call display function and declare another object and call another function;
i know that is working on allocating memory but why we do so.

Commented:
>>why we have to allocate memory when this is working
It is working by chance.
When you declare any (local) variable, it will have junk values and the same holds good for pointers.
And there are chances that the variable initially holds 0 itslef and this is just a coincidence.
Similarly with pointer you are using, by accident it is holding some address which is in the valid range! This may not be the case always! Also, this memory can get allocated to some other variable and your data placed on that address will be lost!!
It's like keeping some dedicated memory and using it.

That's the reason why you have to allocate memory.
The advantage with pointer is that, you can do this dynamically (at runtime). You can allocate and deallocate whenever you want to.
For ordinary variables, the memory gets allocated during compile time and will be there till the lifetime of the variable.

-ssnkumar
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
char * is a POINTER. POINTER points on memory that contains the value. When you don't initialize POINTER in points on some place in memory, that you possibly can access so when you call strcpy it doesn't fail. but it is possible that more that one not initialized POINTERs will point on same memory, so when you'll change one string it will also change another. Also, memory that not initialized POINTER points not marked as "used", so future correct allocations of memory cannot know that your "invalid" POINTER use it, and gives the memory range you use to other objects(variables, stack and etc), so you can corrupt the data in "legal"(correct)code.

Is it clear?
Naman GoelPrincipal Software engineer
CERTIFIED EXPERT

Author

Commented:
but when we use more than use more than one objects using any of these constructor the result come in right way for last constructor but why it is not working for first of these objects.
and when we print length of string in display function it gives the correct length of string why is it so. when the string is not correct.
like
void display()
{
cout<<endl<<s<<strlen(s);
}
and calling these fuction in same way
like this
void main()
{
string s1,s2("language");
cout<<endl<<"values for first object"<<endl;
s1.display();
cout<<endl<<"value for second object"<<endl;
s2.display();
}
would give result like this:-
values for first object

3
values for second object
language
8
why this????

Commented:
If it is working correctly (without allocating memory) in some sequences, then it is just by a chance.
If you allocate memory properly, then it will work in all the different scenarios. You can just try and see!
This itself proves that, without allocating memory your code is not working as expected.

-ssnkumar

Commented:
>>would give result like this:-
>>values for first object
>>
>>3
>>values for second object
>>language
>>8
>>why this????

When you declared s1 and s2, the objects were created on stack. And these contain a pointer, which should hold a valid address. Since you have not assigned a correct/valid address, it is still holding a junk value say X (which is luckily in the valid range).
But by the time you call s1.display(); something else has been written in the place  X (where pointer is pointing to). The reson for this is that, you have not reserved that place and anybody can write anything in this place!!!!

-ssnkumar
efn

Commented:
Here's a more philosophical, rather than technical, explanation.

It is possible to design a programming language so that the behavior of any program can be specified exactly.  It is also possible to design a programming language so that the behavior of some programs is specified exactly by the language design, but the behavior of other possible programs is not specified.  The designer of the C++ language, following the designers of C, designed it so that the behavior of some possible programs is unspecified.  That means that such a program is allowed to do anything when it runs without violating the language specification.  It can turn off the computer's power, erase the hard disk, end quietly, or go into an infinite loop.  A competent programming craftsman tries to avoid creating such programs, because they are not useful, and can be dangerous.

Your program is one of those with unspecified behavior, in both of the cases you are comparing.  You are looking for an explanation of the difference between the cases, but there is no explanation.  Because the behavior is unspecified, you could run the same program at a different time or in a different environment and get different results.  There isn't anything systematic going on that an expert can explain to you.  That's why you are getting all these answers referring to "luck" and "chance."

As a more concrete example of the same thing, consider this code:

int x, y;
cout << x << '\t' << y;

Here x and y are uninitialized.  They could contain any int values.  Even if you ran it over and over and it always put out 13 and 37, there would be no reason for those values, and if you changed other things in the program, those values might change too.  If you asked for an explanation of those values, the only explanation would be "chance," or more verbosely, "because that is one of the many possible run-time behaviors the language design allows for that program."

--efn
Naman GoelPrincipal Software engineer
CERTIFIED EXPERT

Author

Commented:
#include<iostream.h>
#include<string.h>
class string
{
char *s;
public:
string()
{
s=new char[100];
strcpy(s,"c++");
}
string(char * s1)
{
strcpy(s,s1);
}
void display()
{
cout<<endl<<s;
}
};



void main()
{
string s1,s2("language");
s1.display();
s2.display();
}

but why this is not working here we alliocate some memory to s;

Commented:
You have to allocate memory in the overloaded constructor also.
So change your overloaded constructor like this:
string(char * s1)
{
   s=new char[100];
   strcpy(s,s1);
}

One more suggestion. In the display() method, put end of line after displaying the string. Like this:
void display()
{
   cout<<endl<<s<<endl;
}

With these 2 changes your code should work fine on any platform/compiler!
NOTE: Do indentation. Your code will become readable and easy to debug!

-ssnkumar
Take a look the sample I posted before. There is the initstring() function that you should use in EACH constructor you define in class.
Naman GoelPrincipal Software engineer
CERTIFIED EXPERT

Author

Commented:
this is good idea to initialize memory for pointer
but as we know this is not recommanded in c language then why it is so in c.

Commented:
>but as we know this is not recommanded in c language then why it is so in c.
Who told you this!? It is completely wrong.....!
It is a MUST to initialize any variable (including pointers) before using it.
Otherwise, the results will be unexpected!

-ssnkumar
WoW, you can hit the one who told you that!!!
You have to allocate memory !!!

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.