[OT] C++ question re. dyn. mem.

Ask a Question related to Debian, Design and Development.

  1. #1

    Default [OT] C++ question re. dyn. mem.

    Will the free store be properly maintained when the following is executed?
    // a simple object is defined
    typedef struct
    {
    uint32_t a;
    uint64_t b;
    uint8_t c;
    } t_my_type;
    // allocate some memory for an instance of this object
    t_my_type * p_a = (t_my_type) new t_my_type;
    // change the way it is accessed to prove a point
    int * p_b = (int *) p_a;
    // p_a and p_b point to the same block of dyn. allocated memory;
    // return the memory to free storage using the second pointer
    delete p_b;

    I think the free store will be maintained properly because there is a control
    block attached to the allocated block of storage that defines the length of
    the allocated memory.

    TIA,
    --
    Mike Mueller


    --
    To UNSUBSCRIBE, email to [email]debian-user-request@lists.debian.org[/email]
    with a subject of "unsubscribe". Trouble? Contact [email]listmaster@lists.debian.org[/email]
    MJM Guest

  2. Similar Questions and Discussions

    1. Newbie Question: Biz Card Template Question
      Hi, I got the Pagemaker PlugIn - I am using one of the templates for Business Cards - the elements appear to be grouped (bound box all around when I...
  3. #2

    Default Re: [OT] C++ question re. dyn. mem.

    On Sun, Aug 03, 2003 at 10:57:21PM -0400, MJM wrote:
    > Will the free store be properly maintained when the following is executed?
    Yes.

    --
    Pigeon

    Be kind to pigeons
    Get my GPG key here: [url]http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x21C61F7F[/url]

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.0.6 (GNU/Linux)
    Comment: For info see [url]http://www.gnupg.org[/url]

    iD8DBQE/Ln8DUxADjyHGH38RAiB8AJ0eX7ah/1r5qioVgonIMfl2i/vgbwCgjVJz
    NbK3QQq8cNlMGGVY0Lf+ZvM=
    =xFi1
    -----END PGP SIGNATURE-----

    Pigeon Guest

  4. #3

    Default Re: [OT] C++ question re. dyn. mem.

    On Tue, Aug 05, 2003 at 03:40:42AM +0200, Sebastian Kapfer wrote:
    > On Mon, 04 Aug 2003 05:00:12 +0200, MJM wrote:
    > > // change the way it is accessed to prove a point int * p_b = (int *)
    > > p_a;
    > > // p_a and p_b point to the same block of dyn. allocated memory;
    >
    > Do they? Watch out for inheritance, user-defined casting operators and
    > other funny stuff. C++ adds a few new meanings to the () casting syntax.
    > In general, your assumption is _wrong_.
    >
    > > // return the memory to free storage using the second pointer delete
    > > p_b;
    > >
    > > I think the free store will be maintained properly because there is a
    > > control block attached to the allocated block of storage that defines
    > > the length of the allocated memory.
    >
    > No. You have to delete the original pointer (with the original type).
    > Everything else is undefined behaviour, i.e. it could work, it could leak
    > memory (completely or partly), it could crash, or even print "42". It
    > might even work sometimes, and fail mysteriously at other times.
    Interesting. I figured that the actual allocation/deallocation would
    end up being handled by a call to malloc() / free(), and free() only
    cares about having the correct value for the (void *) pointer.

    Would it not be the case, though, in the barebones example given, that
    MJM's '_wrong_ assumption' would be correct, and 'it' would work, even
    if in a more general case it might not?

    Or would it have been better for C++ to have been named D to stop people
    wanting to think like this?

    --
    Pigeon

    Be kind to pigeons
    Get my GPG key here: [url]http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x21C61F7F[/url]

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.0.6 (GNU/Linux)
    Comment: For info see [url]http://www.gnupg.org[/url]

    iD8DBQE/L/EvUxADjyHGH38RAhQNAJ907LiDBhonPD8Ic6hbwV3s/v3OggCcCgEL
    RbbNbXJGaCylLzi6C1w6LUA=
    =q+bg
    -----END PGP SIGNATURE-----

    Pigeon Guest

  5. #4

    Default Re: [OT] C++ question re. dyn. mem.

    On Tue, 05 Aug 2003 22:00:13 +0200, Pigeon wrote:
    >> No. You have to delete the original pointer (with the original type).
    >> Everything else is undefined behaviour, i.e. it could work, it could
    >> leak memory (completely or partly), it could crash, or even print "42".
    >> It might even work sometimes, and fail mysteriously at other times.
    >
    > Interesting. I figured that the actual allocation/deallocation would end
    > up being handled by a call to malloc() / free(), and free() only cares
    > about having the correct value for the (void *) pointer.
    That's how most implementations of C++ work. However, you can't count on
    it. I figure that the stronger requirements which C++ puts on the caller
    of "delete" might allow for more efficient implementation of the C++
    freestore that C's heap did (as a side effect, the size of the memory
    chunk is known without any magic fields). Don't know for sure. And
    finally, don't forget that each C++ class can have an associated
    destructor. For the destructor call, C++ needs to know what kind of object
    we are destroying.

    The relevant quote from Our Holy Standard of C++, section 5.3.5(2), reads:
    > {...} In the first alternative (delete object), the value of the operand
    > of delete shall be a pointer to a non-array object or a pointer to a
    > sub-object (1.8) representing a base class of such an object (clause
    > 10). If not, the behavior is undefined. In the second alternative
    > (delete array), the value of the operand of delete shall be the pointer
    > value which resulted from a previous array new-expression.72) If not,
    > the behavior is undefined. [Note: this means that the syntax of the
    > delete-expression must match the type of the object allocated by new,
    > not the syntax of the new-expression. ] [Note: a pointer to a const type
    > can be the operand of a delete-expression; it is not necessary to cast
    > away the constness (5.2.11) of the pointer expression before it is used
    > as the operand of the delete-expression. ]
    The two "alternatives" here refer to the single-object delete syntax and
    the delete[] syntax for arrays. Please note that the text in square
    brackets was not inserted by me; it's straight from the original.

    The next paragraph (3) discusses derived objects:
    > In the first alternative (delete object), if the static type of the
    > operand is different from its dynamic type, the static type shall be a
    > base class of the operand's dynamic type and the static type shall have
    > a virtual destructor or the behavior is undefined. In the second
    > alternative (delete array) if the dynamic type of the object to be
    > deleted differs from its static type, the behavior is undefined.73)
    The terms "static type" and "dynamic type" don't apply cleanly here (as
    structs and ints aren't related in any way). So I think (2) is more
    relevant (I'm not a language lawyer).

    Footnote 73 is interesting as well:
    > 73) This implies that an object cannot be deleted using a pointer of
    > type void* because there are no objects of type void.
    While footnotes (and the notes above, too) are not part of the normative
    text, they clearly state the intention of the authors.
    > Would it not be the case, though, in the barebones example given, that
    > MJM's '_wrong_ assumption' would be correct, and 'it' would work, even
    > if in a more general case it might not?
    No, it's not correct from the formal point of view. Plus, it's not clean
    code. Nevertheless it _may_ work as expected, depending on the
    implementation of your compiler and the nature of your code.
    > Or would it have been better for C++ to have been named D to stop people
    > wanting to think like this?
    The malloc/free subsystem is still there, and it works the same way as it
    did in C. (Not surprisingly, freeing new'ed objects and deleting malloc'ed
    objects is not formally allowed either.)

    --
    Best Regards, | Hi! I'm a .signature virus. Copy me into
    Sebastian | your ~/.signature to help me spread!


    --
    To UNSUBSCRIBE, email to [email]debian-user-request@lists.debian.org[/email]
    with a subject of "unsubscribe". Trouble? Contact [email]listmaster@lists.debian.org[/email]
    Sebastian Kapfer Guest

  6. #5

    Default Re: [OT] C++ question re. dyn. mem.

    On Tuesday 05 August 2003 14:02, Pigeon wrote:
    > On Tue, Aug 05, 2003 at 03:40:42AM +0200, Sebastian Kapfer wrote:
    > > On Mon, 04 Aug 2003 05:00:12 +0200, MJM wrote:
    > > > // change the way it is accessed to prove a point int * p_b = (int *)
    > > > p_a;
    > > > // p_a and p_b point to the same block of dyn. allocated memory;
    > >
    > > Do they? Watch out for inheritance, user-defined casting operators and
    > > other funny stuff. C++ adds a few new meanings to the () casting syntax.
    > > In general, your assumption is _wrong_.
    Sorry for getting back so late. By assumption are you referring to the
    pointers pointing to the same thing, or that deleting with p_b will correctly
    return what was allocated to p_a? I am convinced that deleting with p_b is
    undefined. I believe it can be managed for safety of the system but the
    practice leads to code that is confusing to read. I think from reading other
    comments that the safest approach is to delete with the same pointer type
    that was used in the allocation.
    > >
    > > > // return the memory to free storage using the second pointer delete
    > > > p_b;
    > > >
    > > > I think the free store will be maintained properly because there is a
    > > > control block attached to the allocated block of storage that defines
    > > > the length of the allocated memory.
    > >
    > > No. You have to delete the original pointer (with the original type).
    > > Everything else is undefined behaviour, i.e. it could work, it could leak
    > > memory (completely or partly), it could crash, or even print "42". It
    > > might even work sometimes, and fail mysteriously at other times.
    >
    > Interesting. I figured that the actual allocation/deallocation would
    > end up being handled by a call to malloc() / free(), and free() only
    > cares about having the correct value for the (void *) pointer.
    >
    > Would it not be the case, though, in the barebones example given, that
    > MJM's '_wrong_ assumption' would be correct, and 'it' would work, even
    > if in a more general case it might not?
    I think this can be true in some implementations.
    >
    > Or would it have been better for C++ to have been named D to stop people
    > wanting to think like this?
    I don't follow the logic there :-) I don't "want" to think like this. The
    reason I asked this question is because I've been doing some rapid protyping
    in a pressure situation. I coded a version of the example above
    inadvertently. In calmer moments I realized what I had done. I was worried
    about memory leaks. I read about alloc and free in the old K&R C book and
    found how there was a hidden header on each allocated block. That block could
    well contain enough information to effect a proper freeing of the block
    regardless of how it was returned. I don't think that the programmer can or
    should rely on such a contrivance since it is not documented officially.

    I have since modified the code to use a template where differant types are
    handled in an explicit manner.
    --
    Mike Mueller


    --
    To UNSUBSCRIBE, email to [email]debian-user-request@lists.debian.org[/email]
    with a subject of "unsubscribe". Trouble? Contact [email]listmaster@lists.debian.org[/email]
    MJM Guest

  7. #6

    Default Re: [OT] C++ question re. dyn. mem.

    On Monday 04 August 2003 21:40, Sebastian Kapfer wrote:
    > >Â*// change the way it is accessed to prove a point int * p_b = (int *)
    > >Â*p_a;
    >
    > Ouch.
    Try this in /usr/src/linux/kernel

    $ grep *\) *.c
    >
    > >Â*// p_a and p_b point to the same block of dyn. allocated memory;
    >
    > Do they?
    They do. My app would be broken from the start if I could not rely on this
    capability. This style of type conversion is covered in elementary C++ books
    by Bjarne. It's not unusual. You must be aware of what you are doing when
    you do a type conversion. Portability is a concern. I am limiting my app to
    Intel 32 bit Linux. Screw everything else.
    > Watch out for inheritance, user-defined casting operators and
    > other funny stuff. C++ adds a few new meanings to the () casting syntax.
    > In general, your assumption is _wrong_.
    I have no user defined casting operators or funny stuff. I'm no fan of
    overloading.
    >
    > One should also note that the C-style casting operator is considered bad
    > style in C++. The "politically correct" way to rewrite your example is
    >
    > int *p_b = reinterpret_cast<int *>(p_a);
    By whom? Your example is nowhere to be found in my C++ books by Bjarne. So
    you are saying that Bjarne promotes bad style in his books? Why not tell him:
    [url]http://www.research.att.com/~bs/homepage.html[/url]

    Besides, reinterpret_cast is probably a template function doing this:

    return ((T) x); // type conversion using cast
    >
    > That way, you're clearly stating the intent of the cast. It is up to your
    > compiler what it makes of this statement; the C++ standard doesn't cover
    > such abuse.
    Language experts sure get their shorts knotted up over simple questions.
    I've known some killer programmers and none of them have quoted a language
    specification in conversation. That was way over the top. That stuff is for
    compiler writers, not application programmers. I did not start a knowledge
    contest. If I did inadvertently, then you win. I just wanted to discuss a
    problem with others of similar interest and try to learn something. I really
    don't care if my code style is bad, abusive, or politically incorrect. I
    just want to make a couple of bucks and make something useful.
    --
    Mike Mueller


    --
    To UNSUBSCRIBE, email to [email]debian-user-request@lists.debian.org[/email]
    with a subject of "unsubscribe". Trouble? Contact [email]listmaster@lists.debian.org[/email]
    MJM Guest

  8. #7

    Default Re: [OT] C++ question re. dyn. mem.

    On Tue, Aug 05, 2003 at 11:21:04PM -0400, MJM wrote:
    > On Monday 04 August 2003 21:40, Sebastian Kapfer wrote:
    > > >*// change the way it is accessed to prove a point int * p_b = (int *)
    > > >*p_a;
    > >
    > > Ouch.
    >
    > Try this in /usr/src/linux/kernel
    >
    > $ grep *\) *.c
    Well, C is not C++, so grepping C source will not really prove anything.
    > > One should also note that the C-style casting operator is considered bad
    > > style in C++. The "politically correct" way to rewrite your example is
    > >
    > > int *p_b = reinterpret_cast<int *>(p_a);
    >
    > By whom? Your example is nowhere to be found in my C++ books by Bjarne. So
    > you are saying that Bjarne promotes bad style in his books? Why not tell him:
    > [url]http://www.research.att.com/~bs/homepage.html[/url]
    Try Meyers' More Effective C++.
    > Besides, reinterpret_cast is probably a template function doing this:
    > return ((T) x); // type conversion using cast
    No, it is an operator, and part of the language. There are four new
    casting operators in C++ that were added to be used in place of the
    C-style cast syntax. If you're writing it C++, you really should use the
    proper casting operators. But, if you only believe things written by
    "Bjarne", try

    [url]http://www.research.att.com/~bs/bs_faq2.html#static-cast[/url]
    > > That way, you're clearly stating the intent of the cast. It is up to your
    > > compiler what it makes of this statement; the C++ standard doesn't cover
    > > such abuse.
    >
    > Language experts sure get their shorts knotted up over simple questions.
    Because your question had to do with undefined and
    implementation-dependent behavior.
    > I've known some killer programmers and none of them have quoted a language
    > specification in conversation. That was way over the top. That stuff is for
    > compiler writers, not application programmers.
    Application programmers should be aware of what aspects of their
    language of choice are not portable or implementation-dependent. That
    includes portability between different compilers and even different
    versions of the same vendor's compiler. That code was not portable, and
    could break just by doing something as innocuous as upgrading the C++
    library.

    --
    Dave Carrigan
    Seattle, WA, USA
    [email]dave@rudedog.org[/email] | [url]http://www.rudedog.org/[/url] | ICQ:161669680
    UNIX-Apache-Perl-Linux-Firewalls-LDAP-C-C++-DNS-PalmOS-PostgreSQL-MySQL


    --
    To UNSUBSCRIBE, email to [email]debian-user-request@lists.debian.org[/email]
    with a subject of "unsubscribe". Trouble? Contact [email]listmaster@lists.debian.org[/email]
    Dave Carrigan Guest

  9. #8

    Default Re: [OT] C++ question re. dyn. mem.

    On Wed, 06 Aug 2003 06:00:11 +0200, MJM wrote:
    > On Monday 04 August 2003 21:40, Sebastian Kapfer wrote:
    >> >Â*// change the way it is accessed to prove a point int * p_b = (int
    >> >*) Â*p_a;
    >>
    >> Ouch.
    >
    > Try this in /usr/src/linux/kernel
    >
    > $ grep *\) *.c
    This is unfair. First, it's kernel-land code, and second I am not aware of
    any C++ code in The Kernel. Call me a fundamentalist, but I think such
    dirty tricks have no gain in modern C++. (There is no alternative in C.)
    >> >Â*// p_a and p_b point to the same block of dyn. allocated memory;
    >>
    >> Do they?
    >
    > They do. My app would be broken from the start if I could not rely on
    > this capability. This style of type conversion is covered in elementary
    > C++ books by Bjarne. It's not unusual.
    Exactly where? I don't remember such casts from Bjarne's book. Maybe with
    a big warning sign next to the code?
    > You must be aware of what you are doing when you do a type conversion.
    > Portability is a concern. I am limiting my app to Intel 32 bit Linux.
    > Screw everything else.
    Well, if you must...
    >> Watch out for inheritance, user-defined casting operators and other
    >> funny stuff. C++ adds a few new meanings to the () casting syntax. In
    >> general, your assumption is _wrong_.
    >
    > I have no user defined casting operators or funny stuff. I'm no fan of
    > overloading.
    What about inheritance? Not a fan either?
    >> One should also note that the C-style casting operator is considered
    >> bad style in C++. The "politically correct" way to rewrite your example
    >> is
    >>
    >> int *p_b = reinterpret_cast<int *>(p_a);
    >
    > By whom? Your example is nowhere to be found in my C++ books by Bjarne.
    > So you are saying that Bjarne promotes bad style in his books? Why not
    > tell him: [url]http://www.research.att.com/~bs/homepage.html[/url]
    My "Bjarne" somewhere recommends using the new-style cast operators. I
    can't provide an actual quote though, since I have the German translation.
    Maybe you have an older edition of the book; the third or fourth should
    cover it.

    BTW, there should be an article about the new casts in the C++ FAQ (I just
    don't find it at the moment). I'm not going to replicate that stuff here,
    since it is probably explained in more detail and better English than I
    can provide. Maybe this can serve as a short intro:

    [url]http://www.hlrs.de/organization/tsc/services/tools/docu/kcc/UserGuide/chapter_9.html[/url]

    Look in section 9.3, "New-Style Casts".
    > Besides, reinterpret_cast is probably a template function doing this:
    >
    > return ((T) x); // type conversion using cast
    Erm... no. It is actually an operator built into the language. And it is
    different from the C-style cast.
    > That way, you're clearly stating the intent of the cast. It is up to
    > your
    >> compiler what it makes of this statement; the C++ standard doesn't
    >> cover such abuse.
    >
    > Language experts sure get their shorts knotted up over simple questions.
    I'm not a language expert, and I'm not a killer programmer either :-)
    > I've known some killer programmers and none of them have quoted a
    > language specification in conversation.
    We're talking about a corner case here.
    > That was way over the top. That stuff is for compiler writers, not
    > application programmers. I did not start a knowledge contest. If I did
    > inadvertently, then you win.
    I don't look at it like a contest. There were two contradicting answers,
    and I wanted to provide proof for mine. Sorry if the language spec was
    over the top, but what else should I have quoted? I don't think I'll find
    any C++ expert who debates our specific example of "delete".
    > I just wanted to discuss a problem with others of similar interest and
    > try to learn something. I really don't care if my code style is bad,
    > abusive, or politically incorrect.
    Well, you now have my opinion on the issue. I won't go after you if you
    prefer to think differently. Please don't feel offended.

    --
    Best Regards, | Hi! I'm a .signature virus. Copy me into
    Sebastian | your ~/.signature to help me spread!


    --
    To UNSUBSCRIBE, email to [email]debian-user-request@lists.debian.org[/email]
    with a subject of "unsubscribe". Trouble? Contact [email]listmaster@lists.debian.org[/email]
    Sebastian Kapfer Guest

  10. #9

    Default Re: [OT] C++ question re. dyn. mem.

    On Wednesday 06 August 2003 01:02, Dave Carrigan wrote:
    > >*Language experts sure get their shorts knotted up over simple questions.
    > > *
    >
    > Because your question had to do with undefined and
    > implementation-dependent behavior.
    I know that. See my other posts. I asked a question about handling dynamic
    memory not type casting. I changed what I was doing to use templates and
    made a container class (probably did it wrong, but I don't care at this
    point).

    I got dragged over the coals for type casting - something used often in the
    kernel. Now there is a suggestion that C++ is not C, the kernel is written
    is C, and so the use of type casting in the kernel does not apply to C++.
    That arguement suggests that C is unclean and C++ is doing things the Right
    Way (if you're smart enough to use it correctly). All this worry over
    casting. It's a wonder that the kernel works on Intel, SPARC, Alpha, etc.
    Funny thing is that while the kernel is working (casts and all), you guys are
    compiling your pure C++ code.

    Type casting works in my application on Intel 32bit Linux. Using casts is
    useful in my work with bit oriented telephony signaling protocols where you
    have to count bits and octets because parameter structures in messages are
    dynamic. I am _not_ going to add all sorts of portability enhancing do-dads
    that make C++ even more difficult to read than it already is. If what I make
    is useful and someone wants it on a different platform, then we'll discuss a
    new project.

    I could spend a lot of time becoming the a better C++ programmer and have
    little time left over for being an application expert. We can't all be C++
    experts and I certainly don't claim to be one. I came for help and I got
    chastised for writing bad code. That is not the usual Debian way from my
    short experience with Debian.

    This experience suggests that some experts like to to make others feel stupid
    and they could care less about helping people with their knowledge. Is this
    how people are treated when they release open source code - language experts
    pouncing on every line of badly written code?

    It is unreasonable to expect application experts to be language experts.
    It's good if they are but it's not necessary. I say it's better to create
    more things with bad code than to create less things with elegant and easily
    portable code. Portability is a job for platform experts. Application
    experts should stick to their knitting. Language experts should ply their
    trade with more respect for the humans that come to them for help.

    Oh, and show your elegant portable code to a rank-and-file programmer for a
    judgement on readability - you'll probably find him or her scratching their
    heads in confusion for a long time. C++ already has a reputation for being
    incomprehensible and thereby difficult to maintain.

    I can see why programming as a profession is fading and why programming jobs
    are going to the lowest bidder. Who wants to pay programmers to create
    issues to argue about instead of creating product?
    --
    Mike Mueller


    --
    To UNSUBSCRIBE, email to [email]debian-user-request@lists.debian.org[/email]
    with a subject of "unsubscribe". Trouble? Contact [email]listmaster@lists.debian.org[/email]
    MJM Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139