Link to home
Create AccountLog in
Avatar of walkman69
walkman69

asked on

2D vector problem in C++

Ok, this is probably a stupid question.. But why do my program crash when the push_back-function is called? At first it's fine, but when I run the program several times, it crashes. It sounds to me like  a memory leak, but why? Doesn't Vector free up memory automatically on program shut down?

wordlist01.dat is a file containing several lines of whatever words you'd like..
example:

a
aa
aan
aaahj
aasfdsfd
aasdfss




#include <iostream>
#include <algorithm>
#include <vector>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <string>
#include <typeinfo>
#include <iterator>

using namespace std;



void showit2(string j) {
	cout << ' ' << j;
}

void showit(vector<string> i) {	
	for_each(i.begin(), i.end(), showit2);
}



int main () {

  time_t time1 = time(NULL);

  char c;
  int n = 0;

  // Initiate 2D vector v, wich contains vector<string> elements.
  vector< vector<string> > v;
  v.reserve(100);

  string theWord;
  int cCount = 0;


  FILE * pFile;
  long lSize;
  char * buffer;
  size_t result;

  pFile = fopen("wordlist01.dat","rb");
  if (pFile==NULL) {fputs ("File error",stderr); exit (1);}

  // obtain file size:
  fseek (pFile , 0 , SEEK_END);
  lSize = ftell (pFile);
  rewind (pFile);

  // allocate memory to contain the whole file:
  buffer = (char*) malloc (sizeof(char)*lSize);
  if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}

  // copy the file into the buffer:
  result = fread (buffer,1,lSize,pFile);
  if (result != lSize) {fputs ("Reading error",stderr); exit (3);}




  /* the whole file is now loaded in the memory buffer. */

  /* 100 below is just a test number, it must be able to loop thru the whole buffer */



  for (int x = 0; x < 100; ++x) {
	
	if (buffer[x] == '\n') {
		
		if ((v[cCount].capacity() - v[cCount].size()) == 0) {
		  // If the capacity is not enough, throw in another 50 elements.
		  v[cCount].reserve(50);
		}

		v[cCount].push_back(theWord);
		cout << theWord;
		
		theWord = "";
		cCount = 0;

	} else {
		theWord += buffer[x];
		cCount++;
	}
  }

  for_each(v.begin(), v.end(), showit); // This doesn't work either.. prints nothing..

  // terminate
  fclose (pFile);
  free (buffer);

  return 0;
}

Open in new window

Avatar of TommySzalapski
TommySzalapski
Flag of United States of America image

Did you run valgrid with --leak-check=full to see where the leaks came from?

Spoiler alert
==1063== HEAP SUMMARY:
==1063==     in use at exit: 3,006 bytes in 14 blocks
==1063==   total heap usage: 43 allocs, 29 frees, 6,937 bytes allocated
==1063==
==1063== 3,006 (2,800 direct, 206 indirect) bytes in 7 blocks are definitely lost in loss record 3 of 3
==1063==    at 0x4A06C8E: operator new(unsigned long) (vg_replace_malloc.c:261)
==1063==    by 0x40296A: __gnu_cxx::new_allocator<std::string>::allocate(unsigned long, void const*) (in /home/tszalapski/software/junk/junk)
==1063==    by 0x402474: std::_Vector_base<std::string, std::allocator<std::string> >::_M_allocate(unsigned long) (in /home/tszalapski/software/junk/junk)
==1063==    by 0x401CBB: std::string* std::vector<std::string, std::allocator<std::string> >::_M_allocate_and_copy<std::string*>(unsigned long, std::string*, std::string*) (in /home/tszalapski/software/junk/junk)
==1063==    by 0x401768: std::vector<std::string, std::allocator<std::string> >::reserve(unsigned long) (in /home/tszalapski/software/junk/junk)
==1063==    by 0x401209: main (in /home/tszalapski/software/junk/junk)
==1063==
==1063== LEAK SUMMARY:
==1063==    definitely lost: 2,800 bytes in 7 blocks
==1063==    indirectly lost: 206 bytes in 7 blocks
==1063==      possibly lost: 0 bytes in 0 blocks
==1063==    still reachable: 0 bytes in 0 blocks
==1063==         suppressed: 0 bytes in 0 blocks
==1063==
==1063== For counts of detected and suppressed errors, rerun with: -v
==1063== Use --track-origins=yes to see where uninitialised values come from
==1063== ERROR SUMMARY: 191 errors from 11 contexts (suppressed: 6 from 6)
Note I also saw several "Conditional jump or move depends on uninitialised value(s)"
Avatar of walkman69
walkman69

ASKER

Actually i'm quite new to C++ in "console-mode" all together, mostly been doing DJGPP, and Visual C++ back in the days.. Took some time just to get up and running learning conversions from old h-libraries to new standards etc.. How do you utilize that valgrid? I'm using minGW g++ compiler.

But uninitialised values?.. I don't think push_back adds the new element without initialising the space first? Sounds strange.. perhaps it has to do with the function call to showit()/showit2().. But that wasn't what caused the crash.. I know that much..
ASKER CERTIFIED SOLUTION
Avatar of TommySzalapski
TommySzalapski
Flag of United States of America image

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
See answer
*sigh*......................................

yea.. so.. not much have changed, have it?..still probably a good idea to initialize an element before trying to use it? lol ^^

I'll have a look at that URL...

tnx ;)