Really having some trouble even phrasing the problem. What's happening is I'm reading and storing an entire binary file into a uint32_t*. Then checking for the start of the segment of data I need. However, adding a check to just make sure I haven't passed over the array changes where the start of the segment is and I have no idea why.
#include <iostream>
#include <string.h>
#include <typeinfo>
#include <fstream>
#include <vector>
#include <stdint.h>
#include <stdexcept>
using namespace std;
int* binmem = new int[32];
streampos size; // size of memblock
int blocklength; // length memblock
uint32_t * memblock; // all data
int startpos;
int endpos;
int x;
void NewParticle() {
startpos = 0;
while (memblock[startpos]!= 0xff000000) { // 4278190080
if (startpos > blocklength) {
//cout << "nah";
//x++;
throw invalid_argument("No start of particle");
}
startpos++;
}
}
int main(int argc, const char *argv[]) {
ifstream file(argv[0], ios::in | ios::binary | ios::ate);
if (file.is_open()) {
size = file.tellg();
blocklength = (size / 4) + (size % 4 == 0 ? 0 : 1);
memblock = new uint32_t[size / 4 + (size % 4 == 0 ? 0 : 1)];
file.seekg(0, ios::beg);
file.read(reinterpret_cast<char*>(memblock), size);
file.close();
NewParticle();
} else
cout << "Unable to open file";
return 0;
}
startpos then varies depending on what condition statement I add into NewParticle(), eg. throwing the exception gives 1109 where as taking the condition out completely gives 812. Using the "nah" makes the while loop run forever and using the x++ statement causes a segment fault... Any idea how these could possibly be changing things? Thank you
You code seems to work if your input is a valid file.
As @RetiredNinja pointed out, possible problems are:
Using
argv [0]
instead ofargv [1]
.argv [0]
will typically point to the name of the executable, which is probably not the file you wish to parse. If you are trying to parse your currently running executable to find your particles, then you have a bad design. So make this change:Run your program like this (for Linux):
or (for Windows):
Or change the default command line arguments in your IDE if you're trying to debug your program.
The value
0xFF000000
is not on an aligned four-byte boundary.For instance, the value could be spread across two
uint32_t
s in your array. This situation is a bit more complicated. You will have to basically iterate through youruint32_t
array with achar*
and look for a0xFF
and see if you can find 30x00
before or after it (depending on endianness).The rest of this answer is just some minor recommendations. You can ignore the rest of this if you want. All of this below assumes problem 2 does not exist.
Here is how I generated a test file for your code:
Managing your own memory is unnecessary. Here's a way to use a
std::vector <uint32_t>
instead of a rawuint32_t*
array:And here's a quick driver that shows how to find your
0xFF000000
value. This requires you to#include <algorithm>
forstd::find()
.