Dicussion 06

Ryan Robucci

Objectives

References

Prereq

If using windows install WSL
Well install build tools including gcc, gdb, and valgrind

GDB

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
gdb 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))

Dynamically Allocated Data structure

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

Valgrind

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$