make av_strdup(NULL) return NULL
[libav.git] / libavutil / mem.c
CommitLineData
d01fe86d 1/*
cea8f6f3 2 * default memory allocator for libavutil
d01fe86d
FB
3 * Copyright (c) 2002 Fabrice Bellard.
4 *
b78e7197
DB
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
d01fe86d
FB
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
b78e7197 10 * version 2.1 of the License, or (at your option) any later version.
d01fe86d 11 *
b78e7197 12 * FFmpeg is distributed in the hope that it will be useful,
d01fe86d
FB
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
b78e7197 18 * License along with FFmpeg; if not, write to the Free Software
5509bffa 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
d01fe86d 20 */
115329f1 21
983e3246
MN
22/**
23 * @file mem.c
cea8f6f3 24 * default memory allocator for libavutil.
983e3246 25 */
115329f1 26
cea8f6f3 27#include "common.h"
8e1e6f31 28
eafcac6a 29/* here we can use OS dependent allocation functions */
8e1e6f31
FB
30#undef malloc
31#undef free
32#undef realloc
33
d01fe86d
FB
34#ifdef HAVE_MALLOC_H
35#include <malloc.h>
36#endif
37
38/* you can redefine av_malloc and av_free in your project to use your
39 memory allocator. You do not need to suppress this file because the
40 linker will do it automatically */
41
18f77016 42void *av_malloc(unsigned int size)
d01fe86d
FB
43{
44 void *ptr;
9ddbcae6 45#ifdef CONFIG_MEMALIGN_HACK
ed96aeea 46 long diff;
88730be6 47#endif
0ecca7a4 48
7d77d5f6 49 /* let's disallow possible ambiguous cases */
0a7c36af 50 if(size > (INT_MAX-16) )
0ecca7a4 51 return NULL;
115329f1 52
9ddbcae6 53#ifdef CONFIG_MEMALIGN_HACK
a9493601
H
54 ptr = malloc(size+16);
55 if(!ptr)
56 return ptr;
ed96aeea 57 diff= ((-(long)ptr - 1)&15) + 1;
90d30570 58 ptr = (char*)ptr + diff;
da9b170c 59 ((char*)ptr)[-1]= diff;
115329f1 60#elif defined (HAVE_MEMALIGN)
8f2b21a8 61 ptr = memalign(16,size);
115329f1 62 /* Why 64?
d01fe86d
FB
63 Indeed, we should align it:
64 on 4 for 386
65 on 16 for 486
bb270c08
DB
66 on 32 for 586, PPro - k6-III
67 on 64 for K7 (maybe for P3 too).
d01fe86d
FB
68 Because L1 and L2 caches are aligned on those values.
69 But I don't want to code such logic here!
70 */
8f2b21a8 71 /* Why 16?
7ce68923 72 Because some CPUs need alignment, for example SSE2 on P4, & most RISC CPUs
8f2b21a8
MN
73 it will just trigger an exception and the unaligned load will be done in the
74 exception handler or it will just segfault (SSE2 on P4)
2cab6401 75 Why not larger? Because I did not see a difference in benchmarks ...
8f2b21a8
MN
76 */
77 /* benchmarks with p3
bb270c08
DB
78 memalign(64)+1 3071,3051,3032
79 memalign(64)+2 3051,3032,3041
80 memalign(64)+4 2911,2896,2915
81 memalign(64)+8 2545,2554,2550
82 memalign(64)+16 2543,2572,2563
83 memalign(64)+32 2546,2545,2571
84 memalign(64)+64 2570,2533,2558
115329f1 85
8f2b21a8
MN
86 btw, malloc seems to do 8 byte alignment by default here
87 */
d01fe86d
FB
88#else
89 ptr = malloc(size);
90#endif
d01fe86d
FB
91 return ptr;
92}
93
8e1e6f31
FB
94void *av_realloc(void *ptr, unsigned int size)
95{
9ddbcae6 96#ifdef CONFIG_MEMALIGN_HACK
0a7c36af
MN
97 int diff;
98#endif
88730be6 99
7d77d5f6 100 /* let's disallow possible ambiguous cases */
a9493601 101 if(size > (INT_MAX-16) )
0ecca7a4
MN
102 return NULL;
103
9ddbcae6 104#ifdef CONFIG_MEMALIGN_HACK
0a7c36af
MN
105 //FIXME this isn't aligned correctly, though it probably isn't needed
106 if(!ptr) return av_malloc(size);
107 diff= ((char*)ptr)[-1];
90d30570 108 return (char*)realloc((char*)ptr - diff, size + diff) + diff;
0a7c36af
MN
109#else
110 return realloc(ptr, size);
da9b170c 111#endif
b7a22d84
MN
112}
113
d01fe86d
FB
114void av_free(void *ptr)
115{
116 /* XXX: this test should not be needed on most libcs */
117 if (ptr)
9ddbcae6 118#ifdef CONFIG_MEMALIGN_HACK
90d30570 119 free((char*)ptr - ((char*)ptr)[-1]);
da9b170c 120#else
d01fe86d 121 free(ptr);
da9b170c 122#endif
d01fe86d
FB
123}
124
79e47000
LB
125void av_freep(void *arg)
126{
127 void **ptr= (void**)arg;
128 av_free(*ptr);
129 *ptr = NULL;
130}
131
132void *av_mallocz(unsigned int size)
133{
11362767 134 void *ptr = av_malloc(size);
79e47000
LB
135 if (ptr)
136 memset(ptr, 0, size);
137 return ptr;
138}
139
140char *av_strdup(const char *s)
141{
fdf35f26
MN
142 char *ptr= NULL;
143 if(s){
ed0d3048 144 int len = strlen(s) + 1;
79e47000
LB
145 ptr = av_malloc(len);
146 if (ptr)
147 memcpy(ptr, s, len);
fdf35f26 148 }
79e47000
LB
149 return ptr;
150}
151