what's the specific of memory allocation in valgrind

Viewed 50

Context: How to make Valgrind log all allocations?
https://valgrind.org/docs/manual/ms-manual.html

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum { NBOOK = 10};
typedef struct{
    char *title;
    int pages;
} book;

typedef struct{
    int num_books,max_books;
    book *array;
} stack;

stack* create_stack();
book *add_book(stack **s,char *title,int pages);
void prn_stack(stack *s);
void free_stack(stack *s);

int main(void){
    stack *s1 = NULL; /* initialize pointers */

    add_book(&s1,"Huck Finn", 631);
    add_book(&s1,"Tom sawyer", 582);
    add_book(&s1,"The qucik brown fox", 1);

    prn_stack(s1);
    free_stack(s1);

    return 0;
}

stack* create_stack()
{
    stack *s = calloc(1,sizeof *s);

    if(!s){
        fprintf(stderr,"error: virtual memory exhausted.--stack\n");
        exit(EXIT_FAILURE);
    }
    
    s->array = calloc(NBOOK,sizeof *(s->array));
    if(!s->array){
        fprintf(stderr,"error: virtual memory exhausted.--array \n");
        exit(EXIT_FAILURE);
    }

    s->num_books = 0;
    s->max_books = NBOOK;
    return s;
}

/** since add_book may create the stack, you must pass the address
 *  of the stack to add_book so that any changes to s are available
 *  back in the calling funciton.
 */
book *add_book(stack **s,char *title,int pages)
{
    if(!title) return NULL;

    if(!*s) *s = create_stack();

    /* check num_books against max_books and realloc as required */
    if((*s)->num_books == (*s)->max_books){
        void *tmp = realloc((*s)->array,((*s)->max_books + NBOOK) * sizeof *((*s)->array));
        if(!tmp){
            fprintf(stderr, "error: memory exhausted - realloc array.\n");
            return NULL;
        }

        (*s)->array = tmp;
        (*s)->max_books += NBOOK;
    }

    /*  allocate/copy title, assign pages, increment num_books  */
    (*s)->array[(*s)->num_books].title = strdup(title);
    (*s)->array[(*s)->num_books].pages = pages;
    ((*s) ->num_books) ++;

    return &((*s)->array[(*s)->num_books - 1]);
}


void prn_stack(stack *s)
{
    if(!s) return;
    
    printf("There are %d books in the stack. maxbook is %d:\n",s->num_books,s->max_books);

    for(int i = 0; i < s->num_books ; i++)
        printf("\t%2d.\t%-20s\t(%3d pages)\n", i,s->array[i].title,s->array[i].pages);

    putchar('\n');
}

void free_stack(stack *s)
{
    if(!s) return;

    for(int i = 0; i < s->num_books; i++)
        free(s->array[i].title);
    free(s->array);
    free(s);
}

gcc -Wformat=2 -Werror=return-type array_struct35.c &&./a.out
valgrind ./a.out

return

-- total heap usage: 6 allocs, 6 frees, 1,241 bytes allocated

valgrind --tool=massif ./a.out
ms_print massif.out.69359

return

94.59% (1,241B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->78.05% (1,024B) 0x48E0C23: _IO_file_doallocate (filedoalloc.c:101)
| ->78.05% (1,024B) 0x48EFD5F: _IO_doallocbuf (genops.c:347)
|   ->78.05% (1,024B) 0x48EEFDF: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:744)
|     ->78.05% (1,024B) 0x48ED754: _IO_new_file_xsputn (fileops.c:1243)
|       ->78.05% (1,024B) 0x48ED754: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1196)
|         ->78.05% (1,024B) 0x48D71CC: outstring_func (vfprintf-internal.c:239)
|           ->78.05% (1,024B) 0x48D71CC: __vfprintf_internal (vfprintf-internal.c:1263)
|             ->78.05% (1,024B) 0x48C281E: printf (printf.c:33)
|               ->78.05% (1,024B) 0x10955F: prn_stack (in /home/jian/helloc/a.out)
|                 ->78.05% (1,024B) 0x1092C8: main (in /home/jian/helloc/a.out)
|
->12.20% (160B) 0x109351: create_stack (in /home/jian/helloc/a.out)
| ->12.20% (160B) 0x1093F0: add_book (in /home/jian/helloc/a.out)
|   ->12.20% (160B) 0x109286: main (in /home/jian/helloc/a.out)
|
->03.12% (41B) 0x490A60E: strdup (strdup.c:42)
| ->03.12% (41B) 0x1094C6: add_book (in /home/jian/helloc/a.out)
|   ->01.60% (21B) in 2 places, all below massif's threshold (1.00%)
|   |
|   ->01.52% (20B) 0x1092BC: main (in /home/jian/helloc/a.out)
|
->01.22% (16B) 0x10930A: create_stack (in /home/jian/helloc/a.out)
  ->01.22% (16B) 0x1093F0: add_book (in /home/jian/helloc/a.out)
    ->01.22% (16B) 0x109286: main (in /home/jian/helloc/a.out)

6 allocated roughly means 6 memory related function call. So far I can only count 5. 5 == 3 strdup() function calls plus 2 calloc) function calls.


update
From https://pubs.opengroup.org/onlinepubs/9699919799/functions/strdup.html I know that strdup function related to memory allocation.

But printf reference https://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html I cannot found memory allocation related info.


I found out this greate question. Does fprintf use malloc() under the hood?

1 Answers

Valgrind will normally free memory that standard libraries allocate (depending on the platform somewhat). It does this by intercepting exit() and calling the libc freeres function in libc (if it finds it).

You can turn this off with

   --run-libc-freeres=<yes|no> [default: yes]

to see these allocations (with memcheck).

Related