Jump to content
  • Advertisement
Sign in to follow this  
NickBarkus

Question About C++ Pointers

This topic is 4058 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi All, I am a bit confused about the char pointer concept. 1)First question that i need to ask is that void SomeFunc() { char *p="hello"; ... } when this function returns will the *p goes out of scope or delete keyword has to be used. 2)Does i need to copy this string with string copy function or it is valid to pass the pointer anywhere i want . or does it goes out of scope ?? class person { public: char* getname() { return "nickbarkus";} ... } please advice - nick-

Share this post


Link to post
Share on other sites
Advertisement
Yes it will go out of scope. What you want to do it create the variable with the use of the 'new' keyword. then return the pointer to the calling function (thereby, allowing you to access the variable)

Share this post


Link to post
Share on other sites
Quote:
Original post by NickBarkus
Hi All,
I am a bit confused about the char pointer concept.

1)First question that i need to ask is that

void SomeFunc()
{
char *p="hello";
...
}
when this function returns will the *p goes out of scope or delete keyword has to be used.

2)Does i need to copy this string with string copy function or it is valid to pass the pointer anywhere i want . or does it goes out of scope ??

class person
{
public:
char* getname()
{ return "nickbarkus";}
...
}

please advice
- nick-
1) No. You only need to call delete on something that is allocated with new

2) Strings like that are special cases, and the pointer will still be valid, yes.

It's worth noting that when you use strings like that, you really should assign them to a const char*, since the compiler could put them in read-only memory.

Share this post


Link to post
Share on other sites
Quote:
Original post by Instigator
Yes it will go out of scope. What you want to do it create the variable with the use of the 'new' keyword. then return the pointer to the calling function (thereby, allowing you to access the variable)
Strings references like that are a special case and will not go out of scope.


The best way to find out is to run the code in the debugger and see what happens. You should be safe if it's a debug build, because the compiler will purposely crap up variables for you.

Share this post


Link to post
Share on other sites
Nick,

Pointers are a difficult concept to grasp initially. The thing about pointers that you have to understand is that they simple hold a memory address.

If you dereference the memory address you get the data that is at that memory address.

Now with your first example

void SomeFunc()
{
char *p="hello";
...
}

the p Pointer is storing the memory address of the 'h', with the rest of the string residing right after it. So in this instance the string "hello" is just like any local variable you declare in the function, when the function dies it destroys it along with everything else. So you cannot use that pointer once that function is done executing.

To get around this you would have to use the new operator. New allocates memory in your heap and so it is independent of functional scope in that regard.

now for part deuce.

You can technically do what your doing there with the returning of the string. But you can only read from the data you cannot modify the string at all. If you want to get it and then modify it inside the caller function you will have to do a strcpy.

class person
{
public:
char* getname()
{ return "nickbarkus";}
...
}

void somefunc()
{
person temp;
char * name;
name = temp.getname(); //You will get "nicbarkus" in name.
name[0] = 'a'; //This will blow UP
cout << name; //This will work
}

This has to do with the way c++ handles char *'s internally it does some weird static allocation thing, not quite sure on that part but i know that much.

If you want to edit the string you will have to do some new / strcpy stuff after you get the name!

Hope this helps.

Share this post


Link to post
Share on other sites
To expand a little further, string literals like that are a special case because they will be placed in a special part of the executable called the string table. The string table collapses multiple uses of the same string into a single entry, which is why the string table is constant (read-only) by necessity -- you can't modify the table entry because there might be some other function looking at it.

This is why the pointer will be valid in this case (because the string is guaranteed to still exist at the same memory location) and why it must be copied to be modified (because you can't modify the table value.)

Share this post


Link to post
Share on other sites
Thank u all and especially GiovanniFreda for ur reply.

1) first part is ok that char *p will be treated as a local variable and will go out of scope when the function returns

2) regarding the second question , when u write string like below ::

void somefunc
{ char *p ="nickbarkus";
....
// what i read was that writing like this create a const string , complier will treat it implicitly thus u cannot make any changes to it.Thus

char* getname()
{ return "nickbarkus";}

returns a const string ?? . Also what i know is that if const string is returned then u have to do like the below :

const char* p=p.getname () // i have not tested it ..
rather then
char* p=p.getname ()

3) New problem :

class person
{
char *name;
public :
person( char* _name):name(_name)
{}
};

main()
{
person p("nickbarkus");
...
// is the above statement a right way of storing name . Is the string supplied to the person constructor goes out of scope when p goes out of scope .

please advice
-nick-

Share this post


Link to post
Share on other sites
You can also you use typedef to rename the pointer so that you don't have to always use the *.

typedef char* STRINGPTR
So you could use as such:

typedef char*STRING;
class Person{
public:
Person();//default constructor
~Person();//destructor
Person(STRING aName);//constructor
Person(Person& aPerson);//Copy constructor
Person operator=(Person& aPerson);//operator overload
.........
private:
STRING name
}
Person::Person(){
STRING = new char[25];
strcpy(name,"nickbarkus");
}
Person::Person(){
delete [] name;
}
Person::Person(STRING aName){
name = new char[strlen(aName)+1];
strcpy(name,aName);
}
Person::Person(Person& aPerson){
name = new char[strlen(aPerson.name)+1];
strcpy(name,aPerson.name);
}
Person operator=(Person& aPerson){
delete [] name;
name = new char[strlen(aPerson.name)+1];
strcpy(name,aPerson.name);
}


That is if you wanted that name to be the default name. I am still kind of new at this so forgive any syntax errors, I did it on the fly..

Share this post


Link to post
Share on other sites
There are actually some interesting questions if you delve a little deeper...

Firstly, and perhaps someone more familiar with this area of the standard can chime in, is this actually defined behavior as per the standard, or is it one of those cases where the implimentation has become the standard? On one hand it seems consistant to treat all string literals this way, on the other it seems reasonable that, under different rules, the strings could be made read/write if they weren't collapsed.

Secondly, is the fact that you can't write the string enforced by the compiler or does it recieve help from the OS? If the former, it must be possible to use some pointer tricks to change the string table but, if I'm not mistaken, its the latter and the OS places the string table into its own write-protection mechanism.


This is one of those C/C++ gotchas in a way. My immediate thought was "Its invalid, because it wasn't dynamically allocated." Not beacuse I didn't know better when I thought about it more but because its a corner case and the common cases simply come to mind first, "overriding" the correct answer.

Share this post


Link to post
Share on other sites
I don't think
char *p = "hello";
would work in the long run since you never allocate space for p. And that would lead to memory corruption.
Rather do
char p[] = "hello";
or
char *somefunc()
{
char *p = new char[strlen("hello")];
strcpy(p, "hello");
return p;
}
char *a = somefunc();
//do something with a
delete [] a;

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!