Ryan Robucci
If using windows install WSL
Well install build tools including gcc, gdb, and valgrind
File bubble.c:
void bubble(int arr[]){ int tmp; for (int i=0;i<(4-1);i++){ if (arr[i+1]<arr[i]){ tmp=arr[i]; arr[i+1]=arr[i]; arr[i]=tmp; } } } int main() { int arr[8]={10,30,20,40}; bubble(arr); return arr[0]; }
gcc -Wall -g -O0 bubble.c
gdb ./a.out
b bubble.c:3
run
b main
b bubble.c:3
info breakpoints
backtrace
(bt
) for seeing the call stackselect-frame 0
select-frame 1
for selecting the frameinfo locals
for list variablesprint &i
or&arr
combined with memory examination ,e.g. x/10b 0x7fffffffdb90set var i=2
for live modification of variablesgdb command | result after select-frame 1 caller main |
result after select-frame 0 function bubble |
note |
---|---|---|---|
print arr | {10, 30, 20, 40, 0, 0, 0, 0} | (int *) 0x7fffffffdb90 | gdb knows the length of the array the command explore arr will invite you to examine an element of the array |
print &arr | (int (*)[8]) 0x7fffffffdb90 | (int **) 0x7fffffffdb68 | pointer to array of eight integers vs. pointer to a pointer to an integer |
print sizeof(arr) | 32 | 8 | an array does not decay into a pointer in the context of the sizeof operator |
print *arr | 10 | 10 | an array decays into a pointer to the first element under most circumstances |
print &(arr[0]) | (int *) 0x7fffffffdb90 | (int *) 0x7fffffffdb90 | both point to the same first element |
print arr+0 | (int *) 0x7fffffffdb90 | (int *) 0x7fffffffdb90 | a shorthand to force decay into a pointer to the first element |
print arr+1 | (int *) 0x7fffffffdb94 | (int *) 0x7fffffffdb94 | pointer arithmetic is handled the same |
print (&arr)+1 | (int (*)[8]) 0x7fffffffdbb0 | (int **) 0x7fffffffdb70 | pointer to array vs pointer to pointer +32 (sizeof length-8 integer array) +8 (sizeof(pointer)) |
Code:
valgrind.c
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct dt1 { int length; char * name; } NODE_t; void makeNode(NODE_t ** ppNode,const char * name){ *ppNode=NULL; //default int len=strlen(name); char * string = malloc(sizeof(char)*(len+1)); if (string==NULL){ return; } *ppNode = malloc(sizeof(NODE_t)); if ((*ppNode)==NULL){ free(string); return; } (*ppNode)->length=len; (*ppNode)->name=string; strcpy((*ppNode)->name,name); } int main(){ NODE_t * ptrNode; const char * name="Robucci"; makeNode (&ptrNode,name); //free(ptrNode->name); free(ptrNode); ptrNode=NULL; printf("leak ?"); return 0; }
Warning
Carefuly understand every line and every bit of syntax in this code
https://valgrind.org/docs/manual/quick-start.html
robucci@sensi:~/GIT/cmpe311/Lectures/CBasics$ valgrind --leak-check=full ./a.out
==800496== Memcheck, a memory error detector
==800496== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==800496== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==800496== Command: ./a.out
==800496==
leak ?==800496==
==800496== HEAP SUMMARY:
==800496== in use at exit: 8 bytes in 1 blocks
==800496== total heap usage: 3 allocs, 2 frees, 1,048 bytes allocated
==800496==
==800496== 8 bytes in 1 blocks are definitely lost in loss record 1 of 1
==800496== at 0x4842839: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==800496== by 0x109219: makeNode (in /tank/robucci/GIT/cmpe311/Lectures/CBasics/a.out)
==800496== by 0x109288: main (in /tank/robucci/GIT/cmpe311/Lectures/CBasics/a.out)
==800496==
==800496== LEAK SUMMARY:
==800496== definitely lost: 8 bytes in 1 blocks
==800496== indirectly lost: 0 bytes in 0 blocks
==800496== possibly lost: 0 bytes in 0 blocks
==800496== still reachable: 0 bytes in 0 blocks
==800496== suppressed: 0 bytes in 0 blocks
==800496==
==800496== For lists of detected and suppressed errors, rerun with: -s
==800496== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
robucci@sensi:~/GIT/cmpe311/Lectures/CBasics$
uncomment //free(ptrNode->name);
robucci@sensi:~/GIT/cmpe311/Lectures/CBasics$ valgrind --leak-check=full ./a.out ==808576== Memcheck, a memory error detector ==808576== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==808576== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info ==808576== Command: ./a.out ==808576== leak ?==808576== ==808576== HEAP SUMMARY: ==808576== in use at exit: 0 bytes in 0 blocks ==808576== total heap usage: 3 allocs, 3 frees, 1,048 bytes allocated ==808576== ==808576== All heap blocks were freed -- no leaks are possible ==808576== ==808576== For lists of detected and suppressed errors, rerun with: -s ==808576== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) robucci@sensi:~/GIT/cmpe311/Lectures/CBasics$