LoginSignup
52
33

More than 5 years have passed since last update.

reallocの怪

Last updated at Posted at 2016-12-13

三行で頼む1

  • realloc(ptr, 0)がfree(ptr)と等価だったのは過去の話
  • reallocの第二引数は絶対に0にするな
  • ISO CもPOSIXも信用するな

C Advent Calendar 201614


bzerobzeroISO CX/OpenUNIXOS使使:
#include <strings.h>

    char buf[42];
    bzero(buf, sizeof (buf));

標準C言語に親しんでいる人間ならば分かると思いますが、これはより汎用的な関数であるところのmemsetを使って次のように書くことができます:

#include <string.h>

    char buf[42];
    memset(buf, 0, sizeof (buf));

bzeromemset99%使0memset

reject使(=)memsetPOSIXbzeroPOSIX:2004POSIX:2008<strings.h>VAXWin32ZeroMemory使

ISO Cmalloc/realloc/calloc/freeISO C:1995(C95)reallocmemset:
ptr = realloc(NULL, size);  /* malloc(size) と等価 */
realloc(ptr, 0);            /* free(ptr) と等価 */

/* 以下はcalloc(memb, size)と等価(ただし掛け算のオーバーフロー時の振る舞いを除く) */
ptr = realloc(NULL, memb*size);
if (ptr)
    memset(ptr, 0, memb*size);

malloccallocfree

realloc(ptr, 0)


bzeroreallocreallocISO C:2011(C11)ISO C:1999(C99)reallocfree

NULLptrrealloc(ptr, 0):

C90/C95
realloc(ptr, 0)NULLptr

C99/C11
realloc(ptr, 0):


NULLptr

ptr



realloc(ptr, 0):


NULLptr

ptr


C90/C95C99/C11


C90/C95  C99/C11 realloc(ptr, 0)free(ptr)(=C90/C95)

C99/C11   NULLptrfree(ptr)(=C99/C11)




reallocfree使C使realloc(ptr, 0)free(ptr)C99

POSIX


POSIXPOSIX:2008C99POSIX:2004C95POSIX:2004Normative ReferenceC99POSIX:2004


realloc(ptr, 0)free(ptr)1999reallocC99C99Defect Report #4003(ptrNULLerrnoISO C):


AIX : realloc(ptr, 0)NULLptr

BSD : realloc(ptr, 0)NULLptr

glibc : realloc(ptr, 0)NULLptr


NULLAIXglibcC90/C95BSDC99/C11BSDC99jemallocC99


realloc0C99

realloc使


ptr

0

NULL


DoSrealloc使

1: 

C90/C95


ISO C:1990/1995C ANSI/ISO/JIS C(P.J.)realloc(CJIS C:1993ISO C:1990/1995):


7.10.3.4 realloc 

#include <stdlib.h>
void *realloc(void *ptr, size_t size);


 reallocptrsizeptrreallocmallocptrcallocmallocreallocfreereallocptrsize0ptrptr


 realloc


調

C99/C11


ANSI/ISO/IEC/9899-1999:


7.20.3 Memory management functions
()
If the size of the space requested is zero, the behavior is implementationdefined: 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.
()

7.20.3.4 The realloc function
Synopsis
#include <stdlib.h>
void *realloc(void *ptr, size_t size);

Description
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 behaves like the malloc function for the specified size. Otherwise, if ptr does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been 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.

Returns
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.


調


DR#400:


7.22.3 Memory management functions
7.22.3.5 The realloc function

If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged.

Ifsize is non-zero and memory for the new object is not allocated, the old object is not deallocated. If size is zero and memory for the new object is not allocated, it is implementation-defined whether the old object is deallocated. If the old object is not deallocated, its value shall be 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.

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 has not been allocated.


7.31 Future library directions
7.31.12 General utilities <stdlib.h>
Invoking realloc with a size argument equal to zero is an obsolescent feature.


調obsolescent

2: C99


C Standard CommitteeDR#4002(N1603(PDF), N1642(PDF))C99

調:


199883(N843)If the realloc function returns a null pointer when size is zero and ptr is not a null pointer, the object it pointed to has been freed.

1998105-9Santa Cruzrealloc rewording(Status of approved proposals for C9X, FCD (Pre-Portland)(N858))


rewordingrewording

C99Annex J (informative) Portability issuesunspecified behavior:

The amount of storage allocated by a successful call to the calloc, malloc, or
realloc function when 0 bytes was requested (7.20.3).

size0(=freeC95) 2016-12-14:C90C90C90
CRationale for International Standard  Programming Languages  C Revision 5.10 April-2003 (PDF):

If the first argument is not null, and the second argument is 0, then the call frees the memory pointed to by the first argument, and a null argument may be returned; C99 is consistent with the policy of not allowing zero-sized objects.

RationaleRationale

脚注


  1. なお、この話はもともとツイッターでやってたものを記事として書き起こしたものです。まとめ 

52
33
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up

52
33