bad_alloc exception. Need help.

Aug 12, 2012 at 1:12pm
I am making a simple program where I store and load binary data for objects However it keeps crashing and it throws a bad_alloc exception and I do not understand why it does it. I think that it has something to do with my my char pointer "buffer" in the read string function in the code below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <iostream>
#include <fstream>
#include "MyDataTypes.h"
#include <string>
#include "IOFunctions.h"

using namespace std;

u8 readu8(ifstream& filein) {
	char byte = 0;
	u8 val = 0;
	filein.read((char*) byte, 1);
	val = byte;
	return val;
}

u16 readu16(ifstream& filein) {
	char bytes[2];
	u16 val = 0;
	filein.read((char*) bytes, 2);
	val = bytes[0] | (bytes[1] << 8);
	return val;
}

u32 readu32(ifstream& filein) {
	char bytes[4];
	u32 val = 0;
	filein.read((char*) bytes, 4);
	val = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | 
		(bytes[3] << 24);
	return val;
}

u64 readu64(ifstream& filein) {
	char bytes[8];
	u64 val = 0;
	filein.read((char*) bytes, 8);
	val = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24) 
		| (static_cast<u64>(bytes[4]) << 32) | (static_cast<u64>(bytes[5]) << 40) | 
		(static_cast<u64>(bytes[6]) << 48) | (static_cast<u64>(bytes[7]) << 56); 
	return val;
}

void writeu8(ofstream& fileout, u8 val) {
	char bytes[1];
	bytes[0] = val;
	fileout.write((char*) bytes, 1);
}

void writeu16(ofstream& fileout, u16 val) {
	char bytes[2];
	bytes[0] = (val & 0xFF);
	bytes[1] = (val & 0xFF00) >> 8;
	fileout.write((char*)bytes, 2);
}

void writeu32(ofstream& fileout, u32 val) {
	char bytes[4];
	bytes[0] = (val & 0xFF);
	bytes[1] = (val & 0xFF00) >> 8;
	bytes[2] = (val & 0xFF0000) >> 16;
	bytes[3] = (val & 0xFF000000) >> 24;
	fileout.write((char*) bytes, 4);
}

void writeu64(ofstream& fileout, u64 val) {
	char bytes[8];
	bytes[0] = (val & 0xFF);
	bytes[1] = (val & 0xFF00) >> 8;
	bytes[2] = static_cast<u8>(val & 0xFF0000) >> 16;
	bytes[3] = static_cast<u8>((val & 0xFF000000) >> 24);
	bytes[4] = static_cast<u8>(static_cast<u64>(val & 0xFF00000000) >> 32);
	bytes[5] = static_cast<u8>(static_cast<u64>(val & 0xFF0000000000) >> 40);
	bytes[6] = static_cast<u8>(static_cast<u64>(val & 0xFF000000000000) >> 48);
	bytes[7] = static_cast<u8>(static_cast<u64>(val & 0xFF00000000000000) >> 56);
	fileout.write((char*)bytes, 8);
} 

string readstring(ifstream& filein) {
	u32 len = readu32(filein);
	char* buffer = new char[len];
	filein.read(buffer, len);
	string str(buffer, len);
	delete[] buffer;
	return str;
}

void writestring(ofstream& fileout, string str) {
	u32 len = str.length();
	writeu32(fileout, len);
	fileout.write(str.c_str(), len);
}


Why do I get this exception?
Aug 12, 2012 at 1:25pm
What's the value of len when the exception is thrown?
Aug 12, 2012 at 1:34pm
Line 12:
1
2
3
4
5
	filein.read((char*) byte, 1);
// should be
	filein.read((char*) &byte, 1);
// although I personally prefer
	filein.read(reinterpret_cast<char *> (&byte), sizeof byte);


Minus style points for the confusing variable name.

Anyway, the std::bad_alloc probably comes from line 81:
char* buffer = new char[len];
Print len. Its value needs to be within... sensible bounds.
Aug 12, 2012 at 1:39pm
Yeah it was the len variable, thank you. It was almost 2 000 000 000 big :O.
Aug 12, 2012 at 1:48pm
It must be something wrong with the readu32() function, since it returns such a high value to the len variable. Can you spot the casue of this? I read through it but I could not see anything that was wrong with it. The first len value should be 8, since it is supposed to read a string of 8 characters.
Last edited on Aug 12, 2012 at 1:49pm
Aug 12, 2012 at 2:12pm
I realized that I had made a call to the wrong function in one place. But now I get another error.

Expression: Invalid null pointer.

File: \....\istream
Line: 721

What noe?

The output window says that I have exited with code: 3
Last edited on Aug 12, 2012 at 2:18pm
Aug 12, 2012 at 2:29pm
Your code is passing a bad value in to a provided function, and way down in istream the bad value is causing a problem. "Invalid null pointer" implies that you're passing a pointer with a zero (NULL) value.

Look at the error messages. Is there a call-stack (list of the function calls leading to the problem)? One of them will be a function you wrote. That's your bad code.

Also, you really, really, really need to learn to debug. Your original problem would have been solved by you in about 30 seconds, and this one much the same.
Aug 12, 2012 at 3:21pm
Ok, the program works fine now and I used the debugger and it really helped and I will consider using it much more now.

I have a question about the casting. When you cast something as a pointer like (char*) x, do you always have to use the adress operator when casting variables and arrays as pointers, like you showed this: "(char*) &byte"?

Thanks for your help.
Aug 12, 2012 at 4:33pm
C arrays decay to the address of their first element.
You can still put a reference operator & in front of their name, but it's redundant.

Plain variables, on the other hand, are their values. Not their address. So you need to put an "address" operator.

Hm... wasn't your null pointer error caused by line 12 by any chance?
Aug 12, 2012 at 4:53pm
A char array is already what read/write expects, so you don't need to cast it:
1
2
3
char data[8];
// Make data
outfile.write(data, 8);


If you use strlen(), make sure your char array is null terminated:
1
2
3
4
char data[9];
// make data
data[8] = '\0';
outfile.write(data, strlen(data));


Using read/write isn't needed for a single char, just use get/put:
1
2
char ch;
while (infile.get(ch)) outfile.put(ch);
Topic archived. No new replies allowed.