I’m not really sure I understand gcc
‘s malloc
attribute correctly.
For example, take a look at this program:
#include <stdio.h>
#include <stdlib.h>
__attribute__((returns_nonnull, malloc, malloc(free, 1)))
void *safe_malloc(size_t n)
{
void *memory = malloc(n);
if (memory == NULL)
{
fprintf(stderr, "failed: malloc(%zu)n", n);
exit(EXIT_FAILURE);
}
return memory;
}
typedef struct
{
size_t n, capacity;
int *elements;
} array_list;
__attribute__((nonnull))
void free_array_list(array_list *lst)
{
if (lst->elements != NULL)
{
free(lst->elements);
}
free(lst);
}
__attribute__((returns_nonnull, malloc, malloc(free_array_list, 1)))
array_list *new_array_list()
{
array_list *lst = safe_malloc(sizeof(array_list));
lst->elements = NULL;
lst->capacity = 0;
lst->n = 0;
return lst;
}
int main(void)
{
array_list *lst = new_array_list();
free_array_list(lst);
return EXIT_SUCCESS;
}
The way I understood __attribute__((..., malloc, malloc(free_array_list, 1)))
was that
malloc
meant, thatnew_array_list
returns new memory similar to malloc, andmalloc(free_array_list, 1)
meant, that the memory returned bynew_array_list
should be released byfree_array_list
.
So kind of similar to an initializer and destructor, new_array_list
returns something that should later be cleaned up by free_array_list
.
But if you compile this piece of code with -fanalyzer
(I’ve tried gcc version 11.3.0
and 12.3.0
) the warning indicates that the memory allocated in new_array_list
by safe_malloc
is leaked.
What am I getting wrong?