lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi, Sean Conner, Adrian,Roberto

I see. I agree with you.
Realloc(3) can fail when shrinking the block.

It seems that Lua has made such an assumption.

As per the documentation(i.e.
https://www.lua.org/manual/5.3/manual.html#lua_Alloc),
which says[emphasise mine]:
Note that Standard C ensures that free(NULL) has no effect and that
realloc(NULL,size) is equivalent to malloc(size).
This code assumes that realloc does not fail when shrinking a block.
(Although Standard C does not ensure this behavior, it seems to be a
safe assumption.)

             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

On Tue, Aug 11, 2020 at 5:36 PM Sean Conner <sean@conman.org> wrote:
>
> It was thus said that the Great 孙世龙 sunshilong once stated:
> > Thank you for your generous help.
> >
> > >> >What matters is what the language
> > >> >standards say, and what they say is that realloc() is permitted to fail
> > >> >when shrinking a block. (Some realloc implementations never fail in that
> > >> >case, but many in common use do.)
> > >> Could you please please give me some references or documents for me to
> > >> go through?
> > >> What about malloc(3) provided by the stand C library?
> > >The realloc function returns a pointer to the new object (which may
> > >have the same value as a pointer to the old object), or a null
> > >pointer if the new object could not be allocated.
> >
> > Thank you for your generous help.
> > But it still can't answer the question:
> > Is realloc(provided by stand C library) permitted to fail when
> > shrinking a block?
>
>   None of the C standards I quoted state that realloc() cannot fail when
> newsize is less than oldsize.  If it's not outright stated, you cannot rely
> upon it being true.  The standard does NOT state that ralloc() CANNOT fail
> when the newsize is less than the oldsize.  So in that sense, yes, realloc()
> CAN fail when newsize is less than oldsize.  You might never encounter a
> system where that happens (much like you will probably never come across a
> system with sign-magnitude integer arithmetic that the C standard allows),
> but that doesn't mean it doesn't exist somewhere.
>
>   It also means that realloc() can return the SAME pointer when growing a
> block (per the wording in the C99/C11 standard---read it closely---it never
> says WHEN it might return the same pointer, only that it MAY):
>
>         #include <stdlib.h>
>         void *realloc(void *ptr,size_t size);
>
>         The realloc function deallocates the old object pointed to by ptr
>                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>         and returns a pointer to a new object that has the size specified by
>         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>         size.  The contents of the new object shall be the same as that of
>         ^^^^
>         the old object prior to deallocation, up to the lesser of the new
>         and old sizes.  Any bytes in the new object beyond the size of the
>         old object have indeterminate values.
>
>         If ptr is a null pointer, the realloc function behhaves like the
>         malloc function for the specfified size.  Otherwise, if ptr does not
>         match a pointer earlier returned by the calloc, malloc, or realloc
>         function, or if the space has deallocated by a call to the free or
>         realloc function, the behavior is undefined.  If memory for the new
>         object cannot be allocated, the old object is not deallocated and
>         its value is unchanged.
>
>         The realloc function returns a pointer to the new object (which may
>                                                                   ^^^^^^^^^
>         have the same value as a pointer to the old object), or a null
>         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>         pointer if the new object could not be allocated.
>
> (emphasis added).  The language is such that any number of implementations
> can be used and still be considered valid.
>
>   All you can really rely upon is checking the return pointer from realloc()
> and handling the case when it returns NULL.  Do NOT assume that shrinking a
> block will always succeed.  Nor assume that the pointer returned from
> realloc() is the same one passed in.
>
>   -spc (Also unstated is what malloc(0), realloc(NULL,0), will return)