Q: Legal use?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jakob Bieling

    Q: Legal use?

    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!
    --
    jb

    (replace y with x if you want to reply by e-mail)


  • Victor Bazarov

    #2
    Re: Legal use?

    "Jakob Bieling" <netsurf@gmy.ne t> wrote...[color=blue]
    > Please have a look at the following snippet:
    >
    > struct base
    > {
    > int* i;
    >
    > base () { i = new int (); }
    > ~base () { delete i; }[/color]

    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.
    [color=blue]
    > };
    >
    > 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!");[/color]


    You mean

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

    , of course...
    [color=blue]
    > }
    >
    > 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[/color]

    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


    Comment

    • Jakob Bieling

      #3
      Re: Legal use?

      "Victor Bazarov" <v.Abazarov@com Acast.net> wrote in message
      news:CCG2c.4970 31$I06.5336338@ attbi_s01...[color=blue]
      > "Jakob Bieling" <netsurf@gmy.ne t> wrote...[color=green]
      > > Please have a look at the following snippet:
      > >
      > > struct base
      > > {
      > > int* i;
      > >
      > > base () { i = new int (); }
      > > ~base () { delete i; }[/color]
      >
      > 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.[/color]

      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.
      [color=blue][color=green]
      > > };
      > >
      > > 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!");[/color]
      >
      >
      > You mean
      >
      > derived *p = new (13) derived;
      > strcpy(p->str, "Hello World!");
      >
      > , of course...[/color]

      Uh, ya, sorry.
      [color=blue][color=green]
      > > }
      > >
      > > The idea is to have the 'derived' class contain a fixed length (*)
      > > char-array, without having to call 'operator new' a second time. Does[/color][/color]
      the[color=blue][color=green]
      > > above produce undefined behaviour?
      > >
      > > (*) but length only known at runtime[/color]
      >
      > 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...[/color]

      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!
      --
      jb

      (replace y with x if you want to reply by e-mail)


      Comment

      Working...