Why is my const pointer not behaving?

D

DamonChong

Hi, I am new and had this piece of code which I created but it is not
behaving as expected. I'm using g++, can someone help me out? Thank
you.

//--------file (Object.cc)-----------
class Object {
public:
Object(const char * c){
id = c;
}

~Object() {}

const char * get_id() const { return id; }

private:
const char * id;
};

//-------file (Test.cc)-------------
#include <iostream>
#include <sstream>
#include "Object.cc"

class Test{
public:
Object ** obj;
Test(){
obj = new Object * [3];
for( int i=0; i<3; i++ ){
std::eek:stringstream os;
os << i;
obj = new Object( os.str().c_str() );
std::cout << "Created id = " << obj->get_id() <<
std::endl;
}
}

~Test(){}
};

int main() {
Test t;
for(int i=0; i<3; i++){
std::cout << "Object id - " << t.obj->get_id()
<< " // expecting " << i << std::endl;
}
}

//----------------output upon running------------
=> ./Test
Created id = 0
Created id = 1
Created id = 2
Object id - 2 // expecting 0
Object id - 2 // expecting 1
Object id - 2 // expecting 2

My query is if I changed the "const char *" to simply int as the
parameter to pass the Object constructor like this and make the
appropriate changes, it works as expected. Now, I know i'm missing
something here!

//---------------file (Object1.cc)-----------------
class Object1 {
public:
Object1(int c){
id = c;
}

~Object1() {}
const int get_id() const { return id; }

private:
int id;
};
 
V

Victor Bazarov

DamonChong said:
Hi, I am new and had this piece of code which I created but it is not
behaving as expected. I'm using g++, can someone help me out? Thank
you.

Your 'Object' class is holding onto a pointer that quickly becomes
invalid. You need to rethink what you store in 'Object' and why. I
recommend making 'id' a "std::string".
 
P

Peter Koch Larsen

I've already advised you not to use pointers. They really should be used
very carefully, and not by beginners. Here your class "Object" should have a
std::string as a member: thus id should be a std::string, not a pointer to
char.
DamonChong said:
Hi, I am new and had this piece of code which I created but it is not
behaving as expected. I'm using g++, can someone help me out? Thank
you.

//--------file (Object.cc)-----------
class Object {
public:
Object(const char * c){
id = c;
}

~Object() {}

const char * get_id() const { return id; }

private:
const char * id;
};

//-------file (Test.cc)-------------
#include <iostream>
#include <sstream>
#include "Object.cc"

class Test{
public:
Object ** obj;
Test(){
obj = new Object * [3];
for( int i=0; i<3; i++ ){
std::eek:stringstream os;
os << i;
obj = new Object( os.str().c_str() );

os.str().c_str() is only valid as long as os is not changed. Thus you keep
tenporary pointers in your newly created object.
std::cout << "Created id = " << obj->get_id() <<
std::endl;
}
}

~Test(){}
};

int main() {
Test t;
for(int i=0; i<3; i++){
std::cout << "Object id - " << t.obj->get_id()
<< " // expecting " << i << std::endl;
}
}

//----------------output upon running------------
=> ./Test
Created id = 0
Created id = 1
Created id = 2
Object id - 2 // expecting 0
Object id - 2 // expecting 1
Object id - 2 // expecting 2

My query is if I changed the "const char *" to simply int as the
parameter to pass the Object constructor like this and make the
appropriate changes, it works as expected. Now, I know i'm missing
something here!


You are missing a good book - perhaps "Accelerated C++", of which I've read
the first chapter. That chapter is very good and the book as a whole has
been praised by all.
[snip]

/Peter
 
D

DamonChong

Ah, now i see. Kind of silly, I bought the book but lend it to someone
instead. Will get it back and go through it, thanks again!
 
R

Ron Natalie

Adieu said:
He's trying to understand constness. That's why he's playing.

The problem is that there is little runtime influence to const.
const like access control is a compile time issue. If it compiles
then the checking has been done. Assuming the compiler actually
enforces constness at the runtime can't be determine without undefined
behavior.
 
O

Old Wolf

Peter said:
DamonChong said:
Object ** obj;
Test(){
obj = new Object * [3];
for( int i=0; i<3; i++ ){
std::eek:stringstream os;
os << i;
obj = new Object( os.str().c_str() );


All of that guff could have been replaced with
Object obj[3]. Or if dynamic sizing is needed,
use a vector. (Assuming Object is copyable).
os.str().c_str() is only valid as long as os is not changed.

It's only valid until the end of the full-expression it
occurs in. But even if you had an implementation where
c_str() was valid until its string changed, os.str()
returns a temporary string anyway, which is destroyed
at the end of the full-expression.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top