Q: Legal use?

J

Jakob Bieling

Hi,

Please have a look at the following snippet:

struct base
{
int* i;

base () { i = new int (); }
~base () { delete i; }
};

struct derived : public base
{
int j;
char str [1];

void* operator new (size_t sz, size_t a) { return malloc (sz + a); }
void operator delete (void* p, size_t a) { free (p); }
};


int main ()
{
derived* = new (13) derived;
strcpy (derived->str, "Hello World!");
}

The idea is to have the 'derived' class contain a fixed length (*)
char-array, without having to call 'operator new' a second time. Does the
above produce undefined behaviour?

(*) but length only known at runtime

Thanks in advance!
 
V

Victor Bazarov

Jakob Bieling said:
Please have a look at the following snippet:

struct base
{
int* i;

base () { i = new int (); }
~base () { delete i; }

Once you at least have read the Rule of Three, there would be red lights
and buzzers going off in your head: if you need to define a destructor,
you most likely need to define a copy constructor and an assignment op.
It may not have relevance here, but I can't pass it up.
};

struct derived : public base
{
int j;
char str [1];

void* operator new (size_t sz, size_t a) { return malloc (sz + a); }
void operator delete (void* p, size_t a) { free (p); }
};


int main ()
{
derived* = new (13) derived;
strcpy (derived->str, "Hello World!");


You mean

derived *p = new (13) derived;
strcpy(p->str, "Hello World!");

, of course...
}

The idea is to have the 'derived' class contain a fixed length (*)
char-array, without having to call 'operator new' a second time. Does the
above produce undefined behaviour?

(*) but length only known at runtime

Why do you ask about UB? What's your suspicions? If they are related
to the use of 'strcpy' and giving it a pointer to the first element of
a one-char array while copying 12 characters there, you may be right
because there seems to be nothing in the Standard that requires a specific
layout of a non-POD object (and your 'derived' is not a POD). So, for all
we know, the 'base' subobject of 'derived' may as well follow the 'str'
array of one char in 'derived'.

Then again, I can be mistaken...

Victor
 
J

Jakob Bieling

Victor Bazarov said:
Once you at least have read the Rule of Three, there would be red lights
and buzzers going off in your head: if you need to define a destructor,
you most likely need to define a copy constructor and an assignment op.
It may not have relevance here, but I can't pass it up.

Yip, I know about it and do keep it in mind when writing production
code. But since this was just an example, I left it out. I added the whole
allocation/c'tor/d'tor stuff to imply that 'base' is not a POD, in case that
might be of relevance to the answer of my question.
};

struct derived : public base
{
int j;
char str [1];

void* operator new (size_t sz, size_t a) { return malloc (sz + a); }
void operator delete (void* p, size_t a) { free (p); }
};


int main ()
{
derived* = new (13) derived;
strcpy (derived->str, "Hello World!");


You mean

derived *p = new (13) derived;
strcpy(p->str, "Hello World!");

, of course...

Uh, ya, sorry.
Why do you ask about UB? What's your suspicions? If they are related
to the use of 'strcpy' and giving it a pointer to the first element of
a one-char array while copying 12 characters there, you may be right
because there seems to be nothing in the Standard that requires a specific
layout of a non-POD object (and your 'derived' is not a POD). So, for all
we know, the 'base' subobject of 'derived' may as well follow the 'str'
array of one char in 'derived'.

Then again, I can be mistaken...

Right, that was exactly what I had in mind. Though, it works for me, I
wanted to know how chances are that it will work with a future compiler I
may use someday. Another concern of mine was padding. Assuming the compiler
used prepends the base class object, can I be sure that there are no padding
bytes between the 'str' member and the 'appended' memory? If not, will this
even be a problem when copying? In my case, copying is not an issue, but I
am just curious.

Thanks for the help!
 

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,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top