fstream does not allocate new memory

Started by
7 comments, last by moucard 19 years, 6 months ago
Ok, I've posted this problem before, but I have a bit of a better grasp on it now. I have a somewhat big project in VC++ .NET (developed in VC++ 6.0 originally). After making a few modifications, one of the ifstream fails to allocate memory for an input file. For example, in the latest installment, I only changed a couple of strings. I added a bigger path to the string (the path exists, I've created it) but when later on I try to open a file with:

ifstream *inFile;
inFile = new ifstream();

inFile.open(.../etc
new return null. I really can't believe I'm running out of memory. Has anybody encountered similar behavior in the past? I've stepped into the functions in fstream, new.cpp, dbgheap.c, handler.cpp and I believe that the system cannot allocate memory. Does anyone see any obvious mistakes I might be missing?
Advertisement
Why do you even need to allocate a stream on the heap for? do you have a container of streams or something?
True that.

Hmmm, we don't seem to have any actual details to work with...
Are you using a good standard library?

I did it to make sure that inFile had a NULL pointer. That happened at some previous modifications. You're right allocating on the stack now allocates enough memory.
But now I have another problem.
I bit later down after I open the file, I have a class called CBall. One of the constructors of this class, takes an ifstream object as an argument and loads some binary data regarding the size, position etc. of the ball. In the specific level I'm trying to load I have 6 balls. Using a for, on the second pass I get an unhandled exception error at xmemory (C++ file I suppose) in:
template<class _Ty> inline	void _Destroy(_Ty _FARQ *_Ptr)	{	// destroy object at _Ptr	_DESTRUCTOR(_Ty, _Ptr);	}}

I use a vector to hold my balls (no pun intended! :) ) like: vector<CBall> m_vBalls;
When I'm trying to load the ball data I use:
for (int i = 0; i < m_siNumberOfBalls; i++) {		m_vBalls.push_back(CBall(inFile));	}

also just for reference my CBall class is:
class CBall  {private:	float m_afColor[3];	float m_afPosition[2];	float m_fSize;	static bool m_bOutlined;		template<class T> std::ostream& WriteBinData(std::ostream& os, const T& data);	template<class T> std::istream& ReadBinData(std::istream& is, T& data);public:	CBall();	CBall(float x, float y);	CBall(float x, float y, float size, float color[3], int outline);	CBall(ifstream &inFile_);	virtual ~CBall();	void SetOutline(bool bOutline_);	void SetColor(float color[3]);	void SetSize(float fSize_);	bool TouchInside(float cursorX_, float cursorY_, float cursorSize_);	bool Touched(float cursorX_, float cursorY_, float cursorSize_);	//float GetEDistance(float pointX_, float pointY_);	bool Clicked(float cursorX_, float cursorY_);	void SaveToFile(ofstream &outFile_);	void SaveToTextFile(ofstream &outFile_);	void LoadFromFile(ifstream &inFile_);	void DrawBall();	void MoveBall(float x, float y);	void MoveBallDif(float x, float y);	void GetInfo(float &x, float &y, float &size);	void GetColor(float color[3]);	bool isOutlined();};

Thanks for your time.
how comes your destructor is virtual? are going derive from CBall? you might wont to check this out:

#include <cstddef>#include <cstdlib>#include <algorithm>#include <iterator>#include <vector>#include <fstream>#include <iostream>class fileball_gen;class ball {  friend class fileball_gen;  float m_afColor[3];  float m_afPosition[2];  float m_fSize;};template < typename T >inline std::ostream& writebin(std::ostream& out, const T& foo, const size_t size = sizeof(T)) {    out.write(reinterpret_cast<const char*>(&foo), size);    return out;}template < typename T >inline std::istream& readbin(std::istream& in, T& foo, const size_t size = sizeof(T)) {   in.read(reinterpret_cast<char*>(&foo), size);   return in;}class fileball_gen {   std::istream& in;public:   fileball_gen(std::istream& _in): in(_in) {}   ball operator()() {      ball b;      readbin(in, b.m_afColor,    sizeof(b.m_afColor) / sizeof(float));      readbin(in, b.m_afPosition, sizeof(b.m_afPosition) / sizeof(float));      readbin(in, b.m_fSize);      return b;   }};int main(int argc, char* argv[]) {    if(argc == 1) {      std::cerr << argv[0] << " error usage: " << argv[0] << " <file-name>\n";      return EXIT_FAILURE;  }  std::ifstream ifs(argv[1], std::ifstream::binary);    if(!ifs) {    std::cerr << argv[0] << " error bad stream\n";    return EXIT_FAILURE;  }  ifs.exceptions(std::ifstream::eofbit | std::ifstream::failbit | std::ifstream::badbit);  std::vector<ball> balls;  const std::vector<ball>::size_type N(30);  balls.reserve(N);  try {     std::generate_n(std::back_inserter(balls), N, fileball_gen(ifs));  } catch(const std::ifstream::failure& e) {     std::cerr << argv[0] << " fatal error, could not read file: " << e.what() << "\n";  }  return EXIT_SUCCESS;}
I explained to you the probable cause of your problem in your last post about this.
Sneftel: I didn't see your answer, I had forgotten the post at that time. I was a bit time pressed. I guess your right, but this is what I'm trying to find out with your help. I guess I've got over-comfortable with vectors and part of the STL when I really don't know them that well. I have to do some reading. But I really need to solve this problem fast! (ok it's not a matter of life and death, but still...)

snk_kid: Thanks for the driver. By using it I've found that it throws the "ios::base failset bit" on the first ball it tries to load.
As for the virtual, I really can't remember why I put it there. Damn my documentation! (Document your code, they said... :) )
But when I comment out the virtual I get the classic LNK2019 linker error: unresolved external symbol "public __thiscall (void)CBall::~CBall(void)"
Also another point it seems interesting is that I have a static member in there:
float m_afColor[3];float m_afPosition[2];float m_fSize;static bool m_bOutlined; <---- static here

which is used for all the balls (they must all be outlined or not). When the destructor is called for CBall where does this member go? (I really need to brush up my C++ skills)
Quote:Original post by moucard
snk_kid: Thanks for the driver. By using it I've found that it throws the "ios::base failset bit" on the first ball it tries to load.


that sort of makes sense because as the code currently is i only guessed the file format, you need adjust the code in the overloaded function call operator in fileball_gen functor appropriately and probably code to read headers and stuff, make sure also your writing the files correctly aswell that can mess you up quite abit.

Quote:Original post by moucard
As for the virtual, I really can't remember why I put it there. Damn my documentation! (Document your code, they said... :) )
But when I comment out the virtual I get the classic LNK2019 linker error: unresolved external symbol "public __thiscall (void)CBall::~CBall(void)"


Its telling you that you haven't defined the member function, as your class doesn't acquire any resources that need to be released on destruction you can just take the destructor completely out (meaning don't even declare it) and let the compiler generate a more appropriate default.

Quote:Original post by moucard
Also another point it seems interesting is that I have a static member in there:
float m_afColor[3];float m_afPosition[2];float m_fSize;static bool m_bOutlined; <---- static here

which is used for all the balls (they must all be outlined or not). When the destructor is called for CBall where does this member go? (I really need to brush up my C++ skills)


well static members are not part of an instance of some type, they get destroyed on program exit not in the destructor not normally that is (note order of destruction is not known & not defined for class/static members).

[Edited by - snk_kid on November 9, 2004 7:56:43 AM]
Hmm, removing the destructor seemed to do the work! I also had to do a full recompile, because it couldn't find ~CBall. The source was changed but VC didn't recompile the object file I guess.
Thank you very much guys, for all your help. You just made a happy man.
So the lesson I should learn from all this is: if the destructor doesn't do anything, just ommit him completely?

This topic is closed to new replies.

Advertisement