-2

I have a very simple class named person which is given below , I have a problem with only two functions , i.e setstring () function and setname() function , I am calling setstring() function from the setname function. The only problem is when in the main function I write
Object.setname(“Zia”);
The result is ok as shown in the output screen, Now when I write
Object.setname(“Zia ur Rahman”);
Nothing is displayed as you can see the output screen.

I know the problem is when I pass the name pointer to setstring () function but I am confused about it please explain it in detail that what is happening here.

#include<iostream.h>
class person
{
char* name;
public:
person();
void setname(const char*);
void setstring(const char*, char*);
void print()const;
};
person::person()
{
name=new char[3];
strcpy(name,"NILL");
name[3]='\0';
}
void person::setstring(const char* s, char*p)
{
if(s!=NULL)
{
delete[] p;
p=new char[strlen(s)];
strcpy(p,s);
p[strlen(s)]='\0';
}
}
void person::setname(const char* n)
{
setstring(n, name);//passing data member name
}
void person::print()const
{
cout<<"Name: "<<name<<endl;
}
main()
{
person object;
object.setname("Zia ur Rahman");
object.print();
system("pause");
}

alt text http://img264.imageshack.us/img264/8867/inheritanceimage004.jpg

alt text http://img263.imageshack.us/img263/3770/inheritanceimage003.jpg

1
  • Just compiled and ran the code. It's a bit messy, but it seems to work well. Commented Jan 21, 2010 at 10:29

7 Answers 7

3

The specific reason that nothing is being printed is that in setstring, p is copy of the name pointer, not a reference to it. Try changing the signature of setstring to:

void setstring(const char* s, char*& p);

(note the &).

See the other answers for other significant errors in the code - unless these problems are fixed, you are likely to get crashes or strange behaviour.

And unless the purpose of the code is just to learn dynamic arrays, use std::string instead :-).

Sign up to request clarification or add additional context in comments.

1 Comment

Nice spot, I didn't see that until I looked again :)
3

If you want to do correct OO-oriented programming in C++ you should maybe stay away from direct pointer management but use the STL string class and use references instead of pointers. Then you should have an easier time and your source should produce the correct output.

Otherwise check your constructor of the person class, the name-array has just 3 elements but you're referencing the 4th one there (indices 0-2!). Also in the setstring() method you're not allocating enough space for the trailing '\0' in the array!

3 Comments

Nothing wrong with pointers, I would say stay away from references they can get you into all type of problems.
Same applies to pointers of course ;) But not the place to start a flamewar here, I had good and bad experiences with both types. Just that I had more good ones with references, but that's my personal experience over the years.
No problem :) Im not the style police patrol. Was just curious.
2

For starters:

name=new char[3];
strcpy(name,"NILL");
name[3]='\0';

name has three elements - you are treating it as if it had five. In a similar vein:

p=new char[strlen(s)];

should be:

p=new char[strlen(s) + 1];

In fact, that function is completely wrong - you are supposed to be copying the string into 'name', not the mysterious 'p' parameter. If you really want that function, then 'p' must be a pointer to a pointer or a reference to a pointer.

2 Comments

O YES, ok i make it correct, but still there is the same problem
when i write object.setname("zia") the output is Name: zia when i write object.setname("Zia ur Rahman") the output is nothing
2

Have you thought about using std::string from STL?

Though first problem I see is this.

person::person()
{
name=new char[3];
strcpy(name,"NILL");
name[3]='\0';
}

Your allocating an array of char's, the size of the array is 3 characters, then your copying "NILL" into it with strcpy so your filling in the array with all the characters but without the null terminator \0. "NILL" is a const string and such has a null terminator that is implicit but not shown for example "NILL\0". The \0 is a control character that is used to indicate the end of the string. Then you have an index out of bounds when you access the 3rd element of name array,when your size of your array is 3.

To help you find out the other parts that could be going wrong, here are some of the links to the function you use.

strcpy
strlen

strcpy will copy the whole string from one buffer to the next including the null terminator control character.

Strlen will return amount of characters between the beginning of the string and the terminating null character. Though it will not count the null character as a character. Thats why you will see suggestions with strlen(string)+1 to include the null terminator.

Though your doing well keep up the work, you will understand these little gotcha when using the standard library functions.

Comments

0

Suppose s have 5 chars. Then new char[strlen(s)]; allocates the memory of 5 chars. Then p[strlen(s)]='\0' is equivalent to p[5]=0. It's very very bad. p[5] does not exsist.

void person::setstring(const char* s, char*p) 
{ 
if(s!=NULL) 
{ 
delete[] p; 
p=new char[strlen(s)]; 
strcpy(p,s); 
p[strlen(s)]='\0';    //<<<< LOOK! Out of range
} 
} 

Comments

0

It's rather C, than C++ code. There is C++ equivalent:

#include <string>
#include <iostream>

class person
{
    std::string name_;
public:
    person();
    //preferable design is to set object invariant in appropriate constructor
    explicit person(const std::string &name);
    std::string get_name() const;
    void set_name(const std::string &name);
    void print()const;
};
person::person()
 : name_("NILL")
{}

person::person(const std::string &name)
: name_(name)
{}

std::string person::get_name() const
{
    return name_;
}

void person::set_name(const std::string &name)
{
    name_ = name;
}
void person::print()const
{
    std::cout<<"Name: "<<name_<<std::endl;
}

int main()
{
    person person1;
    person1.set_name("Zia ur Rahman");
    person1.print();

    //this is better design decision
    //because after constructor we have valid object
    person person2("Zia ur Rahman");
    person2.print();
    std::cin.get();
    return 0;
}

Comments

0

Here main problem is memory allocation .

You have written :

p = new char[strlen(s)];

But Should write

p = new char[ strlen(s) + 1];

If your string s = "Tom" . If write first line then dynamically allocated memory is 3 bytes . And these all bytes will be taken by "Tom" . then You will not have 1 byte for NULL character .

1 Comment

Question asked for detailed explanation of what was wrong. Your answer lacks details and is also not what is actually wrong with their code. Please edit your answer accordingly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.