1 /**
2 * @file
3 * Memory management wrappers
4 *
5 * @authors
6 * Copyright (C) 2017 Richard Russon <rich@flatcap.org>
7 *
8 * @copyright
9 * This program is free software: you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 2 of the License, or (at your option) any later
12 * version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 /**
24 * @page mutt_memory Memory management wrappers
25 *
26 * "Safe" memory management routines.
27 *
28 * @note If any of the allocators fail, the user is notified and the program is
29 * stopped immediately.
30 */
31
32 #include "config.h"
33 #include <stdlib.h>
34 #include "memory.h"
35 #include "exit.h"
36 #include "logging.h"
37 #include "message.h"
38
39 /**
40 * mutt_mem_calloc - Allocate zeroed memory on the heap
41 * @param nmemb Number of blocks
42 * @param size Size of blocks
43 * @retval ptr Memory on the heap
44 *
45 * @note On error, this function will never return NULL.
46 * It will print an error and exit the program.
47 *
48 * The caller should call mutt_mem_free() to release the memory
49 */
mutt_mem_calloc(size_t nmemb,size_t size)50 void *mutt_mem_calloc(size_t nmemb, size_t size)
51 {
52 if ((nmemb == 0) || (size == 0))
53 return NULL;
54
55 void *p = calloc(nmemb, size);
56 if (!p)
57 {
58 mutt_error(_("Out of memory"));
59 mutt_exit(1);
60 }
61 return p;
62 }
63
64 /**
65 * mutt_mem_free - Release memory allocated on the heap
66 * @param ptr Memory to release
67 */
mutt_mem_free(void * ptr)68 void mutt_mem_free(void *ptr)
69 {
70 if (!ptr)
71 return;
72 void **p = (void **) ptr;
73 if (*p)
74 {
75 free(*p);
76 *p = NULL;
77 }
78 }
79
80 /**
81 * mutt_mem_malloc - Allocate memory on the heap
82 * @param size Size of block to allocate
83 * @retval ptr Memory on the heap
84 *
85 * @note On error, this function will never return NULL.
86 * It will print an error and exit the program.
87 *
88 * The caller should call mutt_mem_free() to release the memory
89 */
mutt_mem_malloc(size_t size)90 void *mutt_mem_malloc(size_t size)
91 {
92 if (size == 0)
93 return NULL;
94
95 void *p = malloc(size);
96 if (!p)
97 {
98 mutt_error(_("Out of memory"));
99 mutt_exit(1);
100 }
101 return p;
102 }
103
104 /**
105 * mutt_mem_realloc - Resize a block of memory on the heap
106 * @param ptr Memory block to resize
107 * @param size New size
108 *
109 * @note On error, this function will never return NULL.
110 * It will print an error and exit the program.
111 *
112 * If the new size is zero, the block will be freed.
113 */
mutt_mem_realloc(void * ptr,size_t size)114 void mutt_mem_realloc(void *ptr, size_t size)
115 {
116 if (!ptr)
117 return;
118
119 void **p = (void **) ptr;
120
121 if (size == 0)
122 {
123 if (*p)
124 {
125 free(*p);
126 *p = NULL;
127 }
128 return;
129 }
130
131 void *r = realloc(*p, size);
132 if (!r)
133 {
134 mutt_error(_("Out of memory"));
135 mutt_exit(1);
136 }
137
138 *p = r;
139 }
140