malloc(0)

Discussion in 'C++' started by john smith, Sep 5, 2004.

  1. john smith

    john smith Guest

    Can someone please explain to me what is happening when I do a malloc(0).

    This is what I did.

    int* p = (int*)malloc(0);

    Then I printed the value of p and of course it was non-null.

    But has it allocated memory or what?

    I would think that it would return a null.

    So, can someone please explain what is going on?

    Many thanks.
    john smith, Sep 5, 2004
    #1
    1. Advertising

  2. john smith wrote:
    > int* p = (int*)malloc(0);
    >
    > But has it allocated memory or what? I would think that it would return a null.


    It has indeed. It has allocated a block containing no bytes at all.
    According to the C++ standard, malloc() is the same as in C, and
    the comp.lang.c FAQ says:

    11.26: What should malloc(0) do? Return a null pointer or a pointer to
    0 bytes?

    A: The ANSI/ISO Standard says that it may do either; the behavior
    is implementation-defined (see question 11.33).

    References: ISO Sec. 7.10.3; PCS Sec. 16.1 p. 386.
    --
    Derrick Coetzee
    I grant this newsgroup posting into the public domain. I disclaim all
    express or implied warranty and all liability. I am not a professional.
    Derrick Coetzee, Sep 5, 2004
    #2
    1. Advertising

  3. "john smith" <> wrote...
    > Can someone please explain to me what is happening when I do a malloc(0).
    >
    > This is what I did.
    >
    > int* p = (int*)malloc(0);
    >
    > Then I printed the value of p and of course it was non-null.
    >
    > But has it allocated memory or what?
    >
    > I would think that it would return a null.
    >
    > So, can someone please explain what is going on?


    The behaviour of 'malloc' (and 'calloc' and 'realloc') when the size
    passed in is zero is implementation-defined (so RTFM) and can be
    either of two: the return value is a null pointer or it is non-null
    (as if the size is non-zero), but the pointer cannot be used to access
    an object.

    Victor
    Victor Bazarov, Sep 5, 2004
    #3
  4. john smith

    Kai-Uwe Bux Guest

    john smith wrote:

    > Can someone please explain to me what is happening when I do a malloc(0).
    >
    > This is what I did.
    >
    > int* p = (int*)malloc(0);
    >
    > Then I printed the value of p and of course it was non-null.
    >
    > But has it allocated memory or what?
    >


    Sure, it has allocated a block of length 0. I have no idea what you want to
    do with a block that small, but I am sure that malloc has just allocated a
    block of that size, after all that is what malloc is supposed to do
    according to its man page.


    > I would think that it would return a null.


    Why? It returns the location in memory where the allocated block starts.
    That this block has *length* 0 does not imply that it should start at the
    *location* 0.

    >
    > So, can someone please explain what is going on?
    >


    Nothing is going on: allocating a block of length 0 is pretty useless as
    you can store nothing in there. Yet, be sure to free it once you have no
    need for it anymore.


    > Many thanks.




    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Sep 5, 2004
    #4
  5. Victor Bazarov wrote:

    > john smith wrote:
    >
    >>Can someone please explain to me what is happening when I do a malloc(0).
    >>
    >>This is what I did.
    >>
    >> int* p = (int*)malloc(0);
    >>
    >>Then I printed the value of p and of course it was non-null.
    >>
    >>But has it allocated memory or what?
    >>
    >>I would think that it would return a null.
    >>
    >>So, can someone please explain what is going on?

    >
    > The behaviour of 'malloc' (and 'calloc' and 'realloc')
    > when the size passed in is zero is implementation-defined (so RTFM)
    > and can be either of two:
    > the return value is a null pointer or it is non-null
    > (as if the size is non-zero),
    > but the pointer cannot be used to access an object.


    > cat main.cc

    #include <stdio.h>
    #include <stdlib.h>

    int main(int argc, char* argv[]) {
    if (1 < argc) {
    const
    size_t n = atoi(argv[1]);
    int* p = (int*)malloc(n*sizeof(int));
    fprintf(stdout, "%d = p[-1]\t", p[-1]);

    for (size_t j = 0; j < 4; ++j)
    p[j] = j;

    for (size_t j = 0; j < 4; ++j)
    fprintf(stdout, "%d = p[%d]\t", p[j], j);
    fprintf(stdout, "\n");

    }
    return EXIT_SUCCESS;
    }

    > g++ -Wall -ansi -pedantic -o main main.cc
    > ./main 0

    17 = p[-1] 0 = p[0] 1 = p[1] 2 = p[2] 3 = p[3]
    >. /main 1

    17 = p[-1] 0 = p[0] 1 = p[1] 2 = p[2] 3 = p[3]
    > ./main 2

    17 = p[-1] 0 = p[0] 1 = p[1] 2 = p[2] 3 = p[3]
    > ./main 3

    17 = p[-1] 0 = p[0] 1 = p[1] 2 = p[2] 3 = p[3]
    > ./main 4

    25 = p[-1] 0 = p[0] 1 = p[1] 2 = p[2] 3 = p[3]
    E. Robert Tisdale, Sep 5, 2004
    #5
  6. john smith

    Kai-Uwe Bux Guest

    E. Robert Tisdale wrote:

    > Victor Bazarov wrote:
    >
    >> john smith wrote:
    >>
    >>>Can someone please explain to me what is happening when I do a malloc(0).
    >>>
    >>>This is what I did.
    >>>
    >>>int* p = (int*)malloc(0);
    >>>
    >>>Then I printed the value of p and of course it was non-null.
    >>>
    >>>But has it allocated memory or what?
    >>>
    >>>I would think that it would return a null.
    >>>
    >>>So, can someone please explain what is going on?

    >>
    >> The behaviour of 'malloc' (and 'calloc' and 'realloc')
    >> when the size passed in is zero is implementation-defined (so RTFM)
    >> and can be either of two:
    >> the return value is a null pointer or it is non-null
    >> (as if the size is non-zero),
    >> but the pointer cannot be used to access an object.

    >
    > > cat main.cc

    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > int main(int argc, char* argv[]) {
    > if (1 < argc) {
    > const
    > size_t n = atoi(argv[1]);
    > int* p = (int*)malloc(n*sizeof(int));
    > fprintf(stdout, "%d = p[-1]\t", p[-1]);
    >
    > for (size_t j = 0; j < 4; ++j)
    > p[j] = j;
    >
    > for (size_t j = 0; j < 4; ++j)
    > fprintf(stdout, "%d = p[%d]\t", p[j], j);
    > fprintf(stdout, "\n");
    >
    > }
    > return EXIT_SUCCESS;
    > }
    >
    > > g++ -Wall -ansi -pedantic -o main main.cc
    > > ./main 0

    > 17 = p[-1] 0 = p[0] 1 = p[1] 2 = p[2] 3 = p[3]
    > >. /main 1

    > 17 = p[-1] 0 = p[0] 1 = p[1] 2 = p[2] 3 = p[3]
    > > ./main 2

    > 17 = p[-1] 0 = p[0] 1 = p[1] 2 = p[2] 3 = p[3]
    > > ./main 3

    > 17 = p[-1] 0 = p[0] 1 = p[1] 2 = p[2] 3 = p[3]
    > > ./main 4

    > 25 = p[-1] 0 = p[0] 1 = p[1] 2 = p[2] 3 = p[3]


    And your point is?

    I guess, you wrote a program whose behavior is undefined; and you happend
    to get away with it this time for a particular implementation.

    #include <cstdlib>
    #include <iostream>

    struct xxx {
    char banner [26];
    };

    int main( void ) {
    xxx* p = (xxx*)malloc(0*sizeof(xxx));
    xxx* q = (xxx*)malloc(0*sizeof(xxx));

    std::strcpy( p->banner, "Hello folks, how are you?" );
    std::strcpy( q->banner, "Hello folks, how are you?" );

    std::cout << "p->banner: " << p->banner << "\n";
    std::cout << "q->banner: " << q->banner << "\n";

    return 0;
    }

    > g++ scratch.cc
    > a.out

    p->banner: Hello folks, howHello folks, how are you?
    q->banner: Hello folks, how are you?



    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Sep 5, 2004
    #6
  7. Kai-Uwe Bux wrote:

    > I guess, you wrote a program whose behavior is undefined;
    > and you happend to get away with it this time
    > for a particular implementation.
    >
    > #include <cstdlib>
    > #include <iostream>
    >
    > struct xxx {
    > char banner [26];
    > };
    >
    > int main( void ) {
    > xxx* p = (xxx*)malloc(0*sizeof(xxx));
    > xxx* q = (xxx*)malloc(0*sizeof(xxx));
    >
    > std::strcpy( p->banner, "Hello folks, how are you?" );
    > std::strcpy( q->banner, "Hello folks, how are you?" );
    >
    > std::cout << "p->banner: " << p->banner << "\n";
    > std::cout << "q->banner: " << q->banner << "\n";
    >
    > return 0;
    > }
    >
    >>g++ scratch.cc
    >>a.out

    >
    > p->banner: Hello folks, howHello folks, how are you?
    > q->banner: Hello folks, how are you?


    You should always free storage that you allocate:

    > cat scratch.cc

    #include <cstdlib>
    #include <iostream>

    typedef struct xxx {
    char banner [26];
    } xxx;

    int main(int argc, char* argv[]) {
    xxx* p = (xxx*)malloc(0*sizeof(xxx));
    xxx* q = (xxx*)malloc(0*sizeof(xxx));

    std::strcpy( p->banner, "Hello folks, how are you?" );
    std::strcpy( q->banner, "Hello folks, how are you?" );

    std::cout << "p->banner: " << p->banner << "\n";
    std::cout << "q->banner: " << q->banner << "\n";

    free((void*)q);
    free((void*)p);

    return EXIT_SUCCESS;
    }

    > g++ -Wall -ansi -pedantic -o scratch scratch.cc
    > ./scratch

    p->banner: Hello folks, howHello folks, how are you?
    q->banner: Hello folks, how are you?
    Segmentation fault (core dumped)
    E. Robert Tisdale, Sep 5, 2004
    #7
  8. john smith

    Kai-Uwe Bux Guest

    E. Robert Tisdale wrote:

    > Kai-Uwe Bux wrote:
    >
    >> I guess, you wrote a program whose behavior is undefined;
    >> and you happend to get away with it this time
    >> for a particular implementation.
    >>
    >> #include <cstdlib>
    >> #include <iostream>
    >>
    >> struct xxx {
    >> char banner [26];
    >> };
    >>
    >> int main( void ) {
    >> xxx* p = (xxx*)malloc(0*sizeof(xxx));
    >> xxx* q = (xxx*)malloc(0*sizeof(xxx));
    >>
    >> std::strcpy( p->banner, "Hello folks, how are you?" );
    >> std::strcpy( q->banner, "Hello folks, how are you?" );
    >>
    >> std::cout << "p->banner: " << p->banner << "\n";
    >> std::cout << "q->banner: " << q->banner << "\n";
    >>
    >> return 0;
    >> }
    >>
    >>>g++ scratch.cc
    >>>a.out

    >>
    >> p->banner: Hello folks, howHello folks, how are you?
    >> q->banner: Hello folks, how are you?

    >
    > You should always free storage that you allocate:

    ^^^^^^

    Why?

    In the case under discussion, the operating system will reclaim all
    allocated memory since the program is about to die anyway. I do see no
    point in freeing the memory myself.


    Best

    Kai-Uwe Bux

    >
    > > cat scratch.cc

    > #include <cstdlib>
    > #include <iostream>
    >
    > typedef struct xxx {
    > char banner [26];
    > } xxx;
    >
    > int main(int argc, char* argv[]) {
    > xxx* p = (xxx*)malloc(0*sizeof(xxx));
    > xxx* q = (xxx*)malloc(0*sizeof(xxx));
    >
    > std::strcpy( p->banner, "Hello folks, how are you?" );
    > std::strcpy( q->banner, "Hello folks, how are you?" );
    >
    > std::cout << "p->banner: " << p->banner << "\n";
    > std::cout << "q->banner: " << q->banner << "\n";
    >
    > free((void*)q);
    > free((void*)p);
    >
    > return EXIT_SUCCESS;
    > }
    >
    > > g++ -Wall -ansi -pedantic -o scratch scratch.cc
    > > ./scratch

    > p->banner: Hello folks, howHello folks, how are you?
    > q->banner: Hello folks, how are you?
    > Segmentation fault (core dumped)
    Kai-Uwe Bux, Sep 5, 2004
    #8
  9. Kai-Uwe Bux wrote:
    > E. Robert Tisdale wrote:

    .....
    >
    > Why?
    >
    > In the case under discussion, the operating system will reclaim all
    > allocated memory since the program is about to die anyway. I do see no
    > point in freeing the memory myself.


    While in this particular scenario, you're right, in practice this is the
    exception. Since this is an example, it should demonstrate the more
    general scenario and hence why free() should be called.
    Gianni Mariani, Sep 5, 2004
    #9
  10. john smith

    Jerry Coffin Guest

    "john smith" <> wrote in message news:<>...
    > Can someone please explain to me what is happening when I do a malloc(0).
    >
    > This is what I did.
    >
    > int* p = (int*)malloc(0);
    >
    > Then I printed the value of p and of course it was non-null.
    >
    > But has it allocated memory or what?
    >
    > I would think that it would return a null.


    Using malloc with an argument of 0 gives implementation-defined
    results -- it can return a null pointer or it can return a non-null
    pointer to a block that you can't dereference.

    As an aside, using new instead of malloc would give a non-null pointer
    that you can't dereference (or more accurately, attempting to
    dereference it would give undefined behavior).

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
    Jerry Coffin, Sep 5, 2004
    #10
  11. john smith

    Jack Klein Guest

    On Sun, 05 Sep 2004 02:27:08 -0400, Kai-Uwe Bux <>
    wrote in comp.lang.c++:

    > E. Robert Tisdale wrote:
    > > You should always free storage that you allocate:

    > ^^^^^^
    >
    > Why?
    >
    > In the case under discussion, the operating system will reclaim all
    > allocated memory since the program is about to die anyway. I do see no
    > point in freeing the memory myself.


    Much as I dislike agreeing with the troll Tisdale, he is perfectly
    correct here.

    Exactly where in the C++ standard does it state that allocated memory
    not released by a program will be reclaimed by the operating system?
    Where is the guarantee that this works on all implementations and all
    platforms?

    And of course what happens when someone tries to reuse the code inside
    a larger program by renaming main()?

    Sloppy programming habits should never be encouraged. Or even
    tolerated.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Sep 6, 2004
    #11
  12. john smith

    Jack Klein Guest

    On Sat, 04 Sep 2004 22:50:25 -0400, Kai-Uwe Bux <>
    wrote in comp.lang.c++:

    > john smith wrote:
    >
    > > Can someone please explain to me what is happening when I do a malloc(0).
    > >
    > > This is what I did.
    > >
    > > int* p = (int*)malloc(0);
    > >
    > > Then I printed the value of p and of course it was non-null.
    > >
    > > But has it allocated memory or what?
    > >

    >
    > Sure, it has allocated a block of length 0. I have no idea what you want to
    > do with a block that small, but I am sure that malloc has just allocated a
    > block of that size, after all that is what malloc is supposed to do
    > according to its man page.


    That is one of the two defined actions that malloc() may take. The
    other is to return a null pointer.

    > > I would think that it would return a null.

    >
    > Why? It returns the location in memory where the allocated block starts.
    > That this block has *length* 0 does not imply that it should start at the
    > *location* 0.


    What do you think that a null pointer has to do with location 0? A
    null pointer does not point to location 0. It does not even have an
    all-bits zero representation on all platforms.

    If there is a location 0 on a platform and it is valid for a C (or
    C++) object to reside there, then a pointer to such an object would be
    a pointer to location 0 and it would most specifically not be a null
    pointer.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Sep 6, 2004
    #12
  13. john smith

    David Hilsee Guest

    "E. Robert Tisdale" <> wrote in message
    news:che7lm$iji$...
    > Kai-Uwe Bux wrote:
    >
    > > I guess, you wrote a program whose behavior is undefined;
    > > and you happend to get away with it this time
    > > for a particular implementation.
    > >
    > > #include <cstdlib>
    > > #include <iostream>
    > >
    > > struct xxx {
    > > char banner [26];
    > > };
    > >
    > > int main( void ) {
    > > xxx* p = (xxx*)malloc(0*sizeof(xxx));
    > > xxx* q = (xxx*)malloc(0*sizeof(xxx));
    > >
    > > std::strcpy( p->banner, "Hello folks, how are you?" );
    > > std::strcpy( q->banner, "Hello folks, how are you?" );
    > >
    > > std::cout << "p->banner: " << p->banner << "\n";
    > > std::cout << "q->banner: " << q->banner << "\n";
    > >
    > > return 0;
    > > }
    > >
    > >>g++ scratch.cc
    > >>a.out

    > >
    > > p->banner: Hello folks, howHello folks, how are you?
    > > q->banner: Hello folks, how are you?

    >
    > You should always free storage that you allocate:

    <snip>

    You didn't free the storage in your original example, either. What happens
    when you "correct" it?

    --
    David Hilsee
    David Hilsee, Sep 6, 2004
    #13
  14. john smith

    Kai-Uwe Bux Guest

    Jack Klein wrote:

    > On Sat, 04 Sep 2004 22:50:25 -0400, Kai-Uwe Bux <>
    > wrote in comp.lang.c++:
    >
    >> john smith wrote:
    >>
    >> > Can someone please explain to me what is happening when I do a
    >> > malloc(0).
    >> >
    >> > This is what I did.
    >> >
    >> > int* p = (int*)malloc(0);
    >> >
    >> > Then I printed the value of p and of course it was non-null.
    >> >
    >> > But has it allocated memory or what?
    >> >

    >>
    >> Sure, it has allocated a block of length 0. I have no idea what you want
    >> to do with a block that small, but I am sure that malloc has just
    >> allocated a block of that size, after all that is what malloc is supposed
    >> to do according to its man page.

    >
    > That is one of the two defined actions that malloc() may take. The
    > other is to return a null pointer.


    Actually, I was completely wrong, but maybe notin the way you may have had
    in mind primarily.

    As far as I can tell from the standard, which I have read now, every call
    to malloc, regardless of the argument, may return a null pointer any time.
    As far as I can see, the standard makes no guarantees that calls to malloc
    "succeed". So there is no difference between malloc(0) and malloc(n). The
    standard just allows explicitly that every call malloc(0) may fail,
    however, I cannot see that it does not allow that for other values too. In
    fact, I do not see any language in the standard that would rule out the
    following most useless implementation:

    void* malloc( size_t size ) {
    return( NULL );
    }


    Besides, the OP explictly mentioned that malloc(0) did not return 0 and
    asked what was going on. So, I was describing what happens for a succesful
    call to malloc(0), and I was mistaken on a subtle point. I thought,
    incorrectly, that malloc(0) had allocated a chunk of size 0. In particular,
    I thought that subsequent calls to malloc(0) may return the same pointer.
    That, however, may not be allowed:

    If the size of the space requested is zero, the behavior is
    implementation-defined: either a null-pointer is returned, or
    the behavior is *as if the size were some nonzero value*, except
    that the returned pointer shall not be used to access an object.

    Thus, if malloc(0) does not return 0, it shall behave as though it was
    called with a non-zero argument. I read this to imply that two successive
    calls to malloc(0), neither of which returns 0, must return different
    values. This is an extra requirement that would not otherwise follow from
    the usual requirement that allocated blocks are to be disjoint.


    >> > I would think that it would return a null.

    >>
    >> Why? It returns the location in memory where the allocated block starts.
    >> That this block has *length* 0 does not imply that it should start at the
    >> *location* 0.

    >
    > What do you think that a null pointer has to do with location 0? A
    > null pointer does not point to location 0. It does not even have an
    > all-bits zero representation on all platforms.
    >
    > If there is a location 0 on a platform and it is valid for a C (or
    > C++) object to reside there, then a pointer to such an object would be
    > a pointer to location 0 and it would most specifically not be a null
    > pointer.
    >


    You are right, I was sloppy.

    Just an asside triggered by your remark: is the numerical constant 0 (say
    as an int or unsigned int) required to have an all-bits zeror
    epresentation?


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Sep 6, 2004
    #14
  15. john smith

    Kai-Uwe Bux Guest

    Jack Klein wrote:

    > On Sun, 05 Sep 2004 02:27:08 -0400, Kai-Uwe Bux <>
    > wrote in comp.lang.c++:
    >
    >> E. Robert Tisdale wrote:
    >> > You should always free storage that you allocate:

    >> ^^^^^^
    >>
    >> Why?
    >>
    >> In the case under discussion, the operating system will reclaim all
    >> allocated memory since the program is about to die anyway. I do see no
    >> point in freeing the memory myself.

    >
    > Much as I dislike agreeing with the troll Tisdale, he is perfectly
    > correct here.
    >
    > Exactly where in the C++ standard does it state that allocated memory
    > not released by a program will be reclaimed by the operating system?
    > Where is the guarantee that this works on all implementations and all
    > platforms?
    >


    Interesting question, however, your concern will not be cured by the call
    to free() that was proposed. From the C standard:

    The free function causes the space pointed to by ptr to be deallocated,
    that is, made available for further allocation. ...

    Since this part is inherited by C++, and since C++ does only specify the
    observable behavior of a single instruction sequence, the phrase "available
    for further allocation" just refers to the very C++ programm that is
    calling free(), i.e, subsequence calls to malloc() or new() may now return
    this memory. There is, as far as I can see, no gurantee whatsoever in the C
    or C++ standard that space deallocated by free() or delete() is returned to
    the operating system (thereby becomming available to *other programs*)?

    Where do you get your guarantee that freeing memory works as you seem to
    expect?


    > And of course what happens when someone tries to reuse the code inside
    > a larger program by renaming main()?
    >
    > Sloppy programming habits should never be encouraged. Or even tolerated.


    My understanding of sloppyness is something along the lines of "not
    thinking about what I code". I question rules that contain the word
    "always" or "never" because, more often than not, they encourage sloppyness
    in this sense. For example, reusing main() by renaming without reading it
    would be sloppy.

    Besides, the example was meant to illustrate a point under discussion and
    not teach how to programm -- it exhibits undefined behavior anyway.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Sep 6, 2004
    #15
  16. Kai-Uwe Bux wrote:

    > Thus, if malloc(0) does not return 0, it shall behave as though it was
    > called with a non-zero argument. I read this to imply that two successive
    > calls to malloc(0), neither of which returns 0, must return different
    > values.



    Now we got in this really useless stuff, but the standard does not
    require pointers on different objects to have different values.

    Pointer comparison may happen only for the same object or sequence of
    objects.






    Regards,

    Ioannis Vranos

    http://www23.brinkster.com/noicys
    Ioannis Vranos, Sep 6, 2004
    #16
  17. john smith

    Kai-Uwe Bux Guest

    Ioannis Vranos wrote:

    > Kai-Uwe Bux wrote:
    >
    >> Thus, if malloc(0) does not return 0, it shall behave as though it was
    >> called with a non-zero argument. I read this to imply that two successive
    >> calls to malloc(0), neither of which returns 0, must return different
    >> values.

    >
    >
    > Now we got in this really useless stuff, but the standard does not
    > require pointers on different objects to have different values.
    >
    > Pointer comparison may happen only for the same object or sequence of
    > objects.
    >


    For comparisions of pointers to objects not in the same sequence, I think
    the standard allows the use of std::less< PointerType > and its relatives.
    By 20.3.3/8 this is supposed to yield a total order.

    Nonetheless, I am confused. I was thinking that malloc(n) is inherited from
    C and governed by the language of the C standard with some modifications
    from 20.4.6. Thus, malloc() returns void* (whatever that is) and not a
    pointer to some object. The requirement is just that it is alligned
    suitably so that it can be assigned to any pointer variable.

    Moreover, malloc(n) shall, if called successfully, return the lowest byte
    of some chunk of size at least n. Now, how am I to interpret the rule that
    subsequent calls to malloc shall return pointers to disjoint chunks? Do you
    claim that it was permissible for the returned values of type void* to
    agree, yet they would somehow manage to refer to the lowest bytes of
    disjoint chunks of memory?

    I guess, what I claim is that

    #include <iostream>
    #include <functional>

    int main ( void ) {
    void* p = malloc(0);
    void* q = malloc(0);
    if ( ( p != 0 ) && ( q != 0 ) ){
    if ( std::equal_to< void* >()( p, q ) ) {
    std::cout << "unexpected result.\n";
    }
    }
    }

    is not supposed to print something.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Sep 6, 2004
    #17
  18. john smith

    Old Wolf Guest

    Kai-Uwe Bux <> wrote:
    > Ioannis Vranos wrote:
    >
    > > Kai-Uwe Bux wrote:
    > >
    > >> Thus, if malloc(0) does not return 0, it shall behave as though it was
    > >> called with a non-zero argument. I read this to imply that two successive
    > >> calls to malloc(0), neither of which returns 0, must return different
    > >> values.

    > >
    > > Now we got in this really useless stuff, but the standard does not
    > > require pointers on different objects to have different values.


    It does for objects of the same type. I wonder what 'different values'
    means for objects of incompatible types. For example:
    union { int a; float b; } u;
    can you say that &u.a and &u.b are the same value? Is it well-defined
    to compare &u.a to &u.b (even after casting to void *) ? Of course,
    casting to void* means the value may change.

    > > Pointer comparison may happen only for the same object or sequence of
    > > objects.


    Pointers to different objects of compatible types can be checked
    with ==.

    > For comparisions of pointers to objects not in the same sequence, I think
    > the standard allows the use of std::less< PointerType > and its relatives.
    > By 20.3.3/8 this is supposed to yield a total order.


    Useful.

    > Moreover, malloc(n) shall, if called successfully, return the lowest byte
    > of some chunk of size at least n. Now, how am I to interpret the rule that
    > subsequent calls to malloc shall return pointers to disjoint chunks? Do you
    > claim that it was permissible for the returned values of type void* to
    > agree, yet they would somehow manage to refer to the lowest bytes of
    > disjoint chunks of memory?


    No, the values returned by malloc must all be different, ie.
    void *p = malloc(0);
    void *q = malloc(0);
    assert( !p || !q || p != q );
    Old Wolf, Sep 6, 2004
    #18
  19. Old Wolf wrote:
    .... really major nit pick ... excuse me.
    >
    > No, the values returned by malloc must all be different, ie.
    > void *p = malloc(0);
    > void *q = malloc(0);
    > assert( !p || !q || p != q );


    assert( !p || p != q );

    I can move on now that I have removed that thorn :)
    Gianni Mariani, Sep 7, 2004
    #19
  20. john smith

    Kai-Uwe Bux Guest

    Old Wolf wrote:

    > Kai-Uwe Bux <> wrote:
    >> Ioannis Vranos wrote:
    >>
    >> > Kai-Uwe Bux wrote:
    >> >
    >> >> Thus, if malloc(0) does not return 0, it shall behave as though it was
    >> >> called with a non-zero argument. I read this to imply that two
    >> >> successive calls to malloc(0), neither of which returns 0, must return
    >> >> different values.
    >> >
    >> > Now we got in this really useless stuff, but the standard does not
    >> > require pointers on different objects to have different values.

    >
    > It does for objects of the same type. I wonder what 'different values'
    > means for objects of incompatible types. For example:
    > union { int a; float b; } u;
    > can you say that &u.a and &u.b are the same value? Is it well-defined
    > to compare &u.a to &u.b (even after casting to void *) ? Of course,
    > casting to void* means the value may change.
    >


    You can say that &u.a and &u.b have the same value when converted to void*.
    From the standard [5.9]:

    If two pointers point to data members of the same union object, they
    compare equal (after conversion to void*, if necessary).


    >> > Pointer comparison may happen only for the same object or sequence of
    >> > objects.

    >
    > Pointers to different objects of compatible types can be checked
    > with ==.
    >
    >> For comparisions of pointers to objects not in the same sequence, I think
    >> the standard allows the use of std::less< PointerType > and its
    >> relatives. By 20.3.3/8 this is supposed to yield a total order.

    >
    > Useful.
    >


    Essential: you need to have this for containers like std::set<T*>. By 5.9,
    the built in operator< is undefined for T* if the pointers do not happen to
    point to members of the same object or array.


    >> Moreover, malloc(n) shall, if called successfully, return the lowest byte
    >> of some chunk of size at least n. Now, how am I to interpret the rule
    >> that subsequent calls to malloc shall return pointers to disjoint chunks?
    >> Do you claim that it was permissible for the returned values of type
    >> void* to agree, yet they would somehow manage to refer to the lowest
    >> bytes of disjoint chunks of memory?

    >
    > No, the values returned by malloc must all be different, ie.
    > void *p = malloc(0);
    > void *q = malloc(0);
    > assert( !p || !q || p != q );


    That is how I understand the language of the standard, too.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Sep 7, 2004
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John
    Replies:
    13
    Views:
    681
  2. ravi
    Replies:
    0
    Views:
    435
  3. Peter
    Replies:
    34
    Views:
    1,894
    Richard Tobin
    Oct 22, 2004
  4. porting non-malloc code to malloc

    , Feb 18, 2005, in forum: C Programming
    Replies:
    3
    Views:
    458
    Walter Roberson
    Feb 19, 2005
  5. Johs32

    to malloc or not to malloc??

    Johs32, Mar 30, 2006, in forum: C Programming
    Replies:
    4
    Views:
    310
    Captain Winston
    Mar 30, 2006
Loading...

Share This Page