0

I have written a float Stash (linked list) to store floats. And I have deleted the memory that I had allocated in the heap but valgrind tells me there is a memory leak. Please let me know why valgrind is saying so ?

cppFloatStash.h

#ifndef id897
#define id897

struct FloatStash {
 struct node {
    float value;
    node* next;
 }* head;

 void init ( );
 void push ( float a );
 float pop ( );
 float* peek ( );
 void cleanup ( );
};

#endif

cppFloatStash.cpp

#include "cppFloatStash.h"
#include <cassert>
#include <iostream>

void FloatStash::init () {
 head = 0;
}

void FloatStash::push (float a) {
 if (head == 0) {
    head = new node;
    head->value = a;
    head->next = 0;
 } else {
    node* newNode = new node;
    newNode->value = a;
    newNode->next = head;
    head = newNode;
 }
}

float FloatStash::pop () {
 if (head == 0)
    return 0;
 else {
        node* oldHead = head;
        float result = head->value;
        head = head->next;
        delete oldHead;
        return result;
 }
}

float* FloatStash::peek () {
 if (head == 0) {
    return 0;
 }
 else {
    float result = head->value;
    return result;
 }

}

void FloatStash::cleanup () {
 assert(head == 0);
 std::cout << "Stack empty... Have a good one" << std::endl;
}

FloatStashTest.cpp

#include "cppFloatStash.h"
#include <iostream>

int main (int argc, char** argv) {
 FloatStash s1;
 float result = 0;
 s1.init();
 for (float i = 1007; i < 1023; i++) {
     s1.push(i);
 }

 while ((result = s1.pop()) != 0) {
    std::cout << "result : " << result << std::endl;
 }

 s1.cleanup();
 return 0;
}

Valgrind Output :

$ valgrind --tool=memcheck --leak-check=full ./FloatStash
==9787== Memcheck, a memory error detector
==9787== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==9787== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==9787== Command: ./FloatStash
==9787==
result : 1022
result : 1021
result : 1020
result : 1019
result : 1018
result : 1017
result : 1016
result : 1015
result : 1014
result : 1013
result : 1012
result : 1011
result : 1010
result : 1009
result : 1008
result : 1007
Stack empty... Have a good one
==9787==
==9787== HEAP SUMMARY:
==9787==     in use at exit: 26,352 bytes in 190 blocks
==9787==   total heap usage: 272 allocs, 82 frees, 32,384 bytes allocated
==9787==
==9787== 148 (80 direct, 68 indirect) bytes in 1 blocks are definitely lost in loss record 43 of 66
==9787==    at 0x10000AEBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==9787==    by 0x1002AD8D6: __Balloc_D2A (in /usr/lib/system/libsystem_c.dylib)
==9787==    by 0x1002AE21F: __d2b_D2A (in /usr/lib/system/libsystem_c.dylib)
==9787==    by 0x1002AA877: __dtoa (in /usr/lib/system/libsystem_c.dylib)
==9787==    by 0x1002D33E6: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==9787==    by 0x1002FC6C8: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==9787==    by 0x1002E0914: _vsnprintf (in /usr/lib/system/libsystem_c.dylib)
==9787==    by 0x1002E0973: vsnprintf_l (in /usr/lib/system/libsystem_c.dylib)
==9787==    by 0x1002D0E1D: snprintf_l (in /usr/lib/system/libsystem_c.dylib)
==9787==    by 0x10003D752: std::__1::num_put<char, std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > >::do_put(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, std::__1::ios_base&, char, double) const (in /usr/lib/libc++.1.dylib)
==9787==    by 0x1000239AD: std::__1::basic_ostream<char, std::__1::char_traits<char> >::operator<<(float) (in /usr/lib/libc++.1.dylib)
==9787==    by 0x100000F27: main (FloatStashTest.cpp:13)
==9787==
==9787== 2,064 bytes in 1 blocks are possibly lost in loss record 60 of 66
==9787==    at 0x10000B17C: malloc_zone_malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==9787==    by 0x1005E3EFD: _objc_copyClassNamesForImage (in /usr/lib/libobjc.A.dylib)
==9787==    by 0x1005D7182: protocols() (in /usr/lib/libobjc.A.dylib)
==9787==    by 0x1005D7093: readClass(objc_class*, bool, bool) (in /usr/lib/libobjc.A.dylib)
==9787==    by 0x1005D4C13: gc_init (in /usr/lib/libobjc.A.dylib)
==9787==    by 0x1005DC24E: objc_initializeClassPair_internal(objc_class*, char const*, objc_class*, objc_class*) (in /usr/lib/libobjc.A.dylib)
==9787==    by 0x1005E9132: layout_string_create (in /usr/lib/libobjc.A.dylib)
==9787==    by 0x1005D783C: realizeClass(objc_class*) (in /usr/lib/libobjc.A.dylib)
==9787==    by 0x1005D7300: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==9787==    by 0x1005D72E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==9787==    by 0x1005D72E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==9787==    by 0x1005D72E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==9787==
==9787== LEAK SUMMARY:
==9787==    definitely lost: 80 bytes in 1 blocks
==9787==    indirectly lost: 68 bytes in 2 blocks
==9787==      possibly lost: 2,064 bytes in 1 blocks
==9787==    still reachable: 4,096 bytes in 1 blocks
==9787==         suppressed: 20,044 bytes in 185 blocks
==9787== Reachable blocks (those to which a pointer was found) are not shown.
==9787== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==9787==
==9787== For counts of detected and suppressed errors, rerun with: -v
==9787== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 17 from 17)

Please let me know why valgrind says so. I am a beginner in CPP so please feel free to point out my mistakes.

Barmar
  • 741,623
  • 53
  • 500
  • 612
Naveen N
  • 11
  • 1
  • Unrelated to your bug: http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three – Mooing Duck Apr 19 '16 at 00:56
  • I had to change `float* FloatStash::peek ()` to `float FloatStash::peek ()` to get it to compile, but after that I saw no complaints from valgrind about lost memory. But one question. Why use `init` and `cleanup` methods when you could just use the constructor and destructor? – Paul Rooney Apr 19 '16 at 01:26
  • Paul Rooney : Yeah, I changed float* FloatStash::peek() to float FloatStash::peek () to compile. But I still see memory leak. By the way, are you calling valgrind like this : valgrind --tool=memcheck --leak-check=full ./FloatStashTest ? – Naveen N Apr 19 '16 at 02:06

0 Answers0