Large Dynamic MultiDimensional Array Not Working - c++

My code that I have is quite large and complicated so I won't waste your time reading it, but you're going to have to make certain assumtions about variables in it as a result. I will tell you the values of the variables which I have confirmed in the debugger so you know with certainty. Know that I have omitted a lot of unrelated code in here so what you see isn't everything but I have included everything that is relevant.
// This is defined in a class:
char**** m_DataKeys;
// This is in a member function of the same class:
m_DataKeys = new char*** [m_iNumOfHeroes]; // m_iNumOfHeroes = 2
while ( pkvHero )
{
// iHeroNum = 0 and then 1 #define NUM_OF_ABILITIES 4
m_DataKeys[iHeroNum] = new char** [NUM_OF_ABILITIES];
for (int ability = 0; ability < NUM_OF_ABILITIES; ability++)
{
if (pkvExtraData) // only is true when iHeroNum == 1 and ability == 0
{
// iNumOfExtraData == 2
m_DataKeys[iHeroNum][ability] = new char* [iNumOfExtraData];
while ( pkvSubKey )
{
// iCurExtraDataNum increments from 0 to 2
m_DataKeys[iHeroNum][ability][iCurExtraDataNum] = new char [50];
I put a break point on the line
m_DataKeys[iHeroNum] = new char** [NUM_OF_ABILITIES];
Before the line is called and when iHeroNum == 0 the m_DataKeys array looks like:
m_DataKeys | 0x02072a60
pointer | 0xffeeffee
Error : expression cannot be evaluated
Which is expected. After the line gets called it looks like:
m_DataKeys | 0x02072a60
pointer | 0x02496b00
pointer | 0xffeeffee
Error : expression cannot be evaluated
Which seems to look correct. However, since I set a breakpoint there, I hit play and had it hit it on the next loop around, where iHeroNum == 1 now and ran the line and m_DataKeys then looked like this:
m_DataKeys | 0x02072a60
pointer | 0x02496b00
pointer | 0xffeeffee
Error : expression cannot be evaluated
Which is the exact same as before! The line didn't change the array.... At all!
For clarification, m_DataKeys is a 3 dimensional array of character pointers to character arrays of size 50.
I can't figure out why this is happening, it looks like my code is correct. Is it possible that the garbage collector is screwing me over here? Or maybe the new allocator?
Edit: A Symptom of a Larger Problem
Let me elaborate a little more on the structure of my code, because really, this is just a cheap solution to a bigger problem.
I already have structs as one of you wisely suggested:
struct HeroData
{
// Lots o data here
// ...
// .
//
AbilityData* Abilities[NUM_OF_ABILITIES];
}
struct AbilityData
{
// More data here
// ...
// .
CUtlMap<char*,int> ExtraData [MAX_ABILITY_LEVELS];
}
Now when it got complicated and I had to do this DataKeys arrays of pointers to arrays of pointers crap is only when the need arose to be loading in some data to a dynamic structure, where both the keys, the values, and the numbers of data are completely dynamic. So I thought to use a map of char arrays to ints, but the only problem is that I can't store the actual char array in my map, I have to use a char *. I tried defining the map as:
CUtlMap<char[50],int> ExtraData [MAX_ABILITY_LEVELS];
But that really didn't work and it seems sort of strange to me anyway. So, I had to find some place to stick all these ExtraDataKeys and for some reason I thought it cool to do it like this. How can I store char arrays in objects like arrays or maps?

Since you are using pointers as class members, my best guess is that you are violating The Rule Of Three. That is, you did not provide a copy constructor and a copy assignment operator for your class. That usually leads to strange data loss when passing objects of your class around.
Note that no sane C++ programmer would use char****. Here is my best attempt to fix your problem using vectors and strings, but there is probably a much better design for your specific problem:
#include <string>
#include <vector>
class Foo
{
int m_iNumOfHeroes;
std::vector<std::vector<std::vector<std::string> > > m_DataKeys;
enum { NUM_OF_ABILITIES = 4, iNumOfExtraData = 2 };
public:
explicit Foo(int iNumOfHeroes)
: m_iNumOfHeroes(iNumOfHeroes)
, m_DataKeys(m_iNumOfHeroes, std::vector<std::vector<std::string> >
(NUM_OF_ABILITIES, std::vector<std::string>(iNumOfExtraData)))
{
}
};
int main()
{
Foo x(2);
}
In case you have never seen that colon syntax in the constructor before, that is a member initializer list.
I really wish C++ had array bounds checking
std::vector and std::string do have bounds checking if you use the foo.at(i) syntax instead of foo[i]. In Debug mode, even foo[i] has bounds checking enabled in Visual C++, IIRC.

Though the code might be correct, I personally find that working with something like a char **** can get pretty confusing pretty fast.
This is just my personal preference, but I always try to organize things in the most clear and unambiguous way I can, so what I would do in your situation would be something like
struct Ability
{
char extraData[NUM_OF_EXTRA_DATA][50];
};
struct HeroData
{
Ability abilities[NUM_OF_ABILITIES];
};
class Foo
{
// here you can choose a
HeroData *heroArray;
// and then you would alloc it with "heroArray = new HeroData[m_iNumOfHeroes];"
// or you can more simply go with a
std::vector<HeroData> heroVector;
};
I think this makes things more clear, making it easier for you and other programmers working on that code to keep track of what is what inside your arrays.

I think you expect the wrong thing to happen (that the visual display in the debugger would change), even though your code seems correct.
Your debugger displays m_DataKeys, *m_DataKeys and **m_DataKeys, which is the same as m_DataKeys, m_DataKeys[0] and m_DataKeys[0][0]. When you change m_DataKeys[1], you are not going to notice it in your debugger output.
The following might help you: in my debugger (MS Visual Studio 2005), if you enter e.g. m_DataKeys,5 as your watch expression, you will see the first 5 elements of the array, that is, m_DataKeys[0], m_DataKeys[1], ..., m_DataKeys[4] - arranged in a neat table. If this syntax (with the ,5) doesn't work for you, just add m_DataKeys[1] into the debugger's watch window.

Not sure why this didn't occur to me last night, but I was pretty tired. Heres what I decided to do:
struct AbilityData
{
// Stuff
CUtlMap<char*,int> ExtraData [MAX_ABILITY_LEVELS];
char **DataKeys;
}
Thats what my abilityData struct now looks like, and it now works, but now I want to reorganize it to be like:
struct AbilityData
{
// Stuff
CUtlMap<char*,int[MAX_ABILITY_LEVELS]> ExtraData;
char **DataKeys;
}
Because it makes more sense that way, but then I run into the same problem that I had before with the char array. It almost seems like to me it might just be best to ditch the whole map idea and make it like:
struct AbilityData
{
// Stuff
int *ExtraData;
char **DataKeys;
}
Where ExtraData is now also a dynamically allocated array.
The only problem with that is that I now have to get my data via a function which will loop through all the DataKeys, find a matching key for my input string, then return the ExtraData associated with it.

Related

How do you determine the size of a class when reverse engineering?

I've been trying to learn a bit about reverse engineering and how to essentially wrap an existing class (that we do not have the source for, we'll call it PrivateClass) with our own class (we'll call it WrapperClass).
Right now I'm basically calling the constructor of PrivateClass while feeding a pointer to WrapperClass as the this argument...
Doing this populates m_string_address, m_somevalue1, m_somevalue2, and missingBytes with the PrivateClass object data. The dilemma now is that I am noticing issues with the original program (first a crash that was resolved by adding m_u1 and m_u2) and then text not rendering that was fixed by adding mData[2900].
I'm able to deduce that m_u1 and m_u2 hold the size of the string in m_string_address, but I wasn't expecting there to be any other member variables after them (which is why I was surprised with mData[2900] resolving the text rendering problem). 2900 is also just a random large value I threw in.
So my question is how can we determine the real size of a class that we do not have the source for? Is there a tool that will tell you what variables exist in a class and their order (or atleast the correct datatypes or datatype sizes of each variable). I'm assuming this might be possible by processing assembly in an address range into a semi-decompiled state.
class WrapperClass
{
public:
WrapperClass(const wchar_t* original);
private:
uintptr_t m_string_address;
int m_somevalue1;
int m_somevalue2;
char missingBytes[2900];
};
WrapperClass::WrapperClass(const wchar_t* original)
{
typedef void(__thiscall* PrivateClassCtor)(void* pThis, const wchar_t* original);
PrivateClassCtor PrivateClassCtorFunc = PrivateClassCtor(DLLBase + 0x1c00);
PrivateClassCtorFunc(this, original);
}
So my question is how can we determine the real size of a class that
we do not have the source for?
You have to guess or logically deduce it for yourself. Or just guess. If guessing doesn't work out for you, you'll have to guess again.
Is there a tool that will tell you what variables exist in a class and
their order (or atleast the correct datatypes or datatype sizes of
each variable) I'm assuming by decompiling and processing assembly in
an address range.
No, there is not. The type of meta information that describes a class, it's members, etc. simply isn't written out as the program does not need it nor are there currently no facilities defined in the C++ Standard that would require a compiler to generate that information.
There are exactly zero guarantees that you can reliably 'guess' the size of a class. You can however probably make a reasonable estimate in most cases.
The one thing you can be sure of though: the only problem is when you have too little memory for a class instance. Having too much memory isn't really a problem at all (Which is what adding 2900 extra bytes works).
On the assumption that the code was originally well written (e.g. the developer decided to initialise all the variables nicely), then you may be able to guess the size using something like this:
#define MAGIC 0xCD
// allocate a big buffer
char temp_buffer[8092];
memset(temp_buffer, MAGIC, 8092);
// call ctor
PrivateClassCtor PrivateClassCtorFunc = PrivateClassCtor(DLLBase + 0x1c00);
PrivateClassCtorFunc(this, original);
// step backwards until we find a byte that isn't 0xCD.
// Might want to change the magic value and run again
// just to be sure (e.g. the original ctor sets the last
// few bytes of the class to 0xCD by coincidence.
//
// Obviously fails if the developer never initialises member vars though!
for(int i = 8091; i >= 0; --i) {
if(temp_buffer[i] != MAGIC) {
printf("class size might be: %d\n", i + 1);
break;
}
}
That's probably a decent guess, however the only way to be 100% sure would be to stick a breakpoint where you call the ctor, switch to assembly view in your debugger of choice, and then step through the assembly line by line to see what the max address being written to is.

How to pass reference to a string array as a function parameter in runtime when array size is unknown in C++?

The following piece of code works fine. Problem is I need it to work when size of array is unknown. In the example below I have hardcoded the values to 2. In the real world I do not know the size. Is there a way to modify the code so that it works even when size of the array is not known.
void namesArray(std::string (&numList)[2], std::string name)
{
//This is just place holder code. Please ignore the logic.
numList[ 0 ] = "Peter" + name;
numList[ 1 ] = "Bruce" + name;
}
int main()
{
std::string nameList[2];
namesArray( nameList, "Parker");
std::cout << nameList[0]<< std::endl;
std::cout << nameList[1] << std::endl;
return 0;
}
I CANNOT use any other datatype (eg: Vectors) except Arrays due to external limitations.
Edit: When I say the size is unknown, what I mean is the size of the Array is not known until runtime.
Also, what I am presenting is an over simplification of my actual code. The function accepts only arrays.
UPDATE: Thank you all for the solutions offered. Looks like the code I have already authored worked in my solution. I know it's wierd to use arrays when vetors offer more flexibility. However, when dealing with legacy code you sometimes don't have a choice. THANKS A LOT FOR ALL THE ANSWERS TO EVERYONE WHO RESPONDED. IT WAS VERY INFORMATIVE.
If I understood your question well, you can use template mechanism to array size deduction:
#include <iostream>
#include <string>
template <size_t N>
void namesArray(std::string (&numList)[N], std::string name) {
//This is just place holder code. Please ignore the logic.
numList[ 0 ] = "Peter" + name;
numList[ 1 ] = "Bruce" + name;
}
int main() {
std::string nameList[5];
namesArray( nameList, "Parker");
std::cout << nameList[0]<< std::endl;
std::cout << nameList[1] << std::endl;
return 0;
}
You got presented several solutions. I'd like to present another, one that is an abstraction which incorporates several solutions. Take a gsl::span (or a std::span if you are from the future).
A span is generalized a view on a contiguous sequence of elements. And a powerful abstraction.
You want to pass an array of static size? A span can be constructed from one via a template constructor.
You want to pass a pointer and a size? span got you covered there as well.
A container like std::vector or std::array? No problem.
Use a span if all you care about is the sequence property, and not what the sequence itself is.
The simplest solution is to pass the size in with the array:
void namesArray(std::string *numList, std::size_t numCount, std::string name)
This will probably work for you -- you need to know the size of the array when you pass it in, but it doesn't require that you be working with a stack array from that scope, and in general usage you're more likely to have access to the size of the array than to be creating the array in the same scope that you're calling the function. It also makes things much more explicit and, if you switch to heap arrays instead of stack arrays, it still works fine.
Here's the thing: You always know the size of the array. It's literally impossible to write code that creates an array of an unknown size. You can (un)intentionally forget the array size, but at some point, it has to be known, because you literally can't create the array otherwise. You might only know it at runtime, because it's, say, defined by user input, but that just means it's in a variable, and you still know it, you just don't have it predefined at compile time.
Also, if the array size is defined at runtime, you're using heap arrays, and the other solution won't work for that.

How to overcome null pointer initialisation error? (C/C++)

I'm having a hard time figuring out why the initialisation at NULL of one pointer is bugging my program.
In order to not receive a compilation error, almost all the pointers in my code need to be initialise as nullptr like usual. Problem is, when I tried to use them afterwards, I get a whole bunch of errors telling me the null pointer is invalid. To overcome this error, the buggy pointers are now declare as an array. This way all my problems with this initialisation are gone. Everything seems to work fine until I realise one of my conditional branch was always returning false.
The full code is a bit too long and some parts use french words, so let's just paste what interest us...
struct Numero {
int num;
char client[50];
Message *listeMessage = nullptr;
Numero *suivant = nullptr;
int nbmsg = 0;
};
char buff_char[50];
number = new Numero;
file >> number->client; // getting the right char client[50] from the file
if (number->client == buff_char)
break;
I also tried if(*number->client == *buff_char) without success. I'm now thinking that the problem is probably the array of char, but because of my previous problem I can't really change that so I'm hoping somebody can figure out what's going on here.
Note: Don't suggest anything related to strings, I can't use them because it's part of the challenge here to practice with pointers.
number->client == buff_char
Both of these are arrays, which decay into pointers. They are two different arrays with two different addresses, so this will always return false.
*number->client == *buff_char
This would compare the first element in each array, which is also not what you want.
You can use a standard library function like strcmp.
If you can't use the standard library, loop over each array until one has a different element than the other (not equal), they both have '\0' (equal), or they both reach 50 (equal).
In If do a comparison instead of assignment
if (number->client == buff_char)
In C++ = is the assignment operator. You want == for equality. What your if statement does right now is sets client equal to buff_char and then evaluates based on the newly assigned value of client.

Can we scramble the declaration order in C or C++?

Is there a method/plugin/addon in place to ignore the following clause (for some c/c++ compiler)? To reorder the declaration of members in a struct during the same stage as the preprocessor or similar? Perhaps by adding a keyword like volatile or something similar to the front of the struct declaration.
I was thinking: a compiler option, a built-in keyword, or a programming method.
C99 §6.7.2.1 clause 13 states:
Within a structure object, the
non-bit-field members and the units in
which bit-fields reside have addresses
that increase in the order in which
they are declared.
C++ seems to have a similar clause, and I am interested in that as well. The clauses both specify a reasonable feature to have in terms of later declarations have greater memory offsets. But, I often do not need to know the declaration order of my struct for interface purposes or some other. It would be nice to write some code like:
scrambled struct foo {
int a;
int bar;
};
or, suppose order doesn't really matter with this struct.
scrambled struct foo {
int bar;
int a;
};
And so, have the declaration of a and b swapped randomly each time I compile. I believe that this also applies to setting aside stack memory.
main() {
scrambled int a;
scrambled int foo;
scrambled int bar;
..
Why do I ask?
I was curious to see how program bots were created. I watched some people analyzing memory offsets for changes while running the program to which a hack will be created.
It seems the process is: watch the memory offsets and take note of the purpose for the given offsets. Later, hack programs will inject desired values into memory at those offsets.
Now suppose those memory offsets changed every single time the program is compiled. Maybe it would hinder or dissuade individuals from taking the time to understand something you would rather they not know.
Run-time foxing is the best way, then you only have to release a single version. Where a struct has several fields of the same type, you can use an array instead. Step 1. Instead of a structure with three int fields use an array
#define foo 0
#define bar 1
#define zee 2
struct abc {
int scramble [3];
};
...
value = abc.scramble[bar];
Step 2, now use an indexing array which is randomised every time the program is run.
int abcindex [3]; // index lookup
int abcpool [3]; // index pool for randomise
for (i=0; i<3; i++) // initialise index pool
abcpool[i] = i;
srand (time(NULL));
for (i=0; i<3; i++) { // initialise lookup array
j = rand()%(3-i);
abcindex[i] = abcpool[j]; // allocate random index from pool
abcpool[j] = abcpool[2-i]; // remove index from pool
}
value = abc.scramble[abcindex[bar]];
Another way to try to fox a hacker is to include subterfuge variables that behave as if they have something to do with it but make the program exit if tampered with. Lastly you can keep some kind of checksum or encrypted copy of key variables, to check if they have been tampered with.
Your intention is good, but the solution isn't (sorry). Usually you can't recompile your program before each run. The attacker will hack the inspected program. However, there's a solution, called ASLR. The operating system could change the load address for you, thus making "return oriented programming" and "return to libc like hacks harder".

Segmentation fault in File I/O

I have written a code to read a file, store it in a structure and just display it. But somehow it is giving me a segmentation fault and I dont know why. Can someone please help me?
Output:
file: /home/neel/map2.txt
file opened
Start Intersection
a->road: 4
a->roadId[0]: 1
a->lane[0][0]: 2
a->lane[0][1]: 2
a->roadId[1]: 2
a->lane[1][0]: 2
a->lane[1][1]: 2
a->roadId[2]: 3
Segmentation fault
Code:
#include <iostream>
#include <fstream>
#include <stdio.h>
using namespace std;
struct Intersection
{
unsigned short road;
long long int *roadId;
short *lane[2];
};
int main(int argc, char** argv)
{
std::ifstream file;
cout<<"file: "<<argv[1]<<endl;
file.open(argv[1], std::ios::in);
cout<<"file opened"<<endl;
while (!file.eof())
{
cout<<"Start Intersection"<<endl;
Intersection *a = new Intersection;
file>>a->road;
a->roadId = new long long int[a->road];
a->lane[0] = new short[a->road];
a->lane[1] = new short[a->road];
cout<<"a->road: "<<a->road<<endl;
for (int i=0; i<a->road; i++)
{
file>>a->roadId[i];
cout<<endl<<"a->roadId["<<i<<"]: "<<a->roadId[i]<<endl;
file>>a->lane[i][0];
cout<<"a->lane["<<i<<"][0]: "<<a->lane[i][0]<<endl;
file>>a->lane[i][1];
cout<<"a->lane["<<i<<"][1]: "<<a->lane[i][1]<<endl;
}
cout<<"Intersection inserted"<<endl;
delete a;
}
}
Text file:
4
1
2
2
2
2
2
3
2
2
4
2
2
Your lane is an array of 2 elements, however when i reaches 2 in your inner loop you are trying to print a->lane[2][0], which doesn't exist.
file>>a->lane[i][0]; //wrong
file>>a->lane[i][1]; //wrong
The indices should be reverse:
file>>(a->lane[0][i]); //correct
file>>(a->lane[1][i]); //correct
I added brackets just for clarity.
Besides, there is memory leak in your program. There should be as many delete as there are new statements, to ensure that there is no memory leak. So write these:
delete [] a->roadId;
delete [] a->lane[0];
delete [] a->lane[1];
delete a; //you've written only this!
Note delete a should be the last statement when deallocating the memory!
I don't mean to be nasty, but this code has enough problems it's almost difficult to decide which ones to start with.
using namespace std;
Here's the first red flag. About all I can say is that using namespace std; is a poor idea. With other namespaces it can be acceptable, but with std, it should always be avoided (IMO).
struct Intersection
{
unsigned short road;
long long int *roadId;
short *lane[2];
};
This strikes me as a pretty poorly designed structure. std::vector is a good thing. Use it. Rather than just a structure of dumb data, you might want to consider defining operator>> for your structure type, so you can read one directly. Even if you don't do that, from the way you're using it, what you really want is something more like:
struct road {
long long Id;
short lane[2];
};
struct Intersection {
int road_count;
road *roads;
};
Then, rather than a couple of parallel arrays all the same size that have to be walked in parallel, you get a a number of roads, each with its own data. std::vector is still better though.
int main(int argc, char** argv)
{
std::ifstream file;
cout<<"file: "<<argv[1]<<endl;
file.open(argv[1], std::ios::in);
Rather than defining an ifstream object and then opening it separately, you should normally plan on passing the name to the ctor so it's defined and opened in a single operation, something like:
std::ifstream file(argv[1]);
But, you also normally want to add a bit of error checking so you only attempt to use the command line argument as a file name if one has been passed, something like this:
if (argc < 2) {
std::cerr << "Usage: your_command <filename>\n";
return EXIT_FAILURE;
}
Then you'd have the code to define the ifstream.
while (!file.eof())
Here's another major problem. A loop of this form is essentially always wrong (including this case, from the looks of things).
cout<<"Start Intersection"<<endl;
Intersection *a = new Intersection;
There seems to be no reason to allocate this dynamically. Are you, perhaps, a recovering (or perhaps not recovering) Java or C# programmer? Java requires that all objects of user defined classes be allocated dynamically, but C++ does not.
file>>a->road;
a->roadId = new long long int[a->road];
a->lane[0] = new short[a->road];
a->lane[1] = new short[a->road];
cout<<"a->road: "<<a->road<<endl;
for (int i=0; i<a->road; i++)
{
file>>a->roadId[i];
cout<<endl<<"a->roadId["<<i<<"]: "<<a->roadId[i]<<endl;
file>>a->lane[i][0];
cout<<"a->lane["<<i<<"][0]: "<<a->lane[i][0]<<endl;
file>>a->lane[i][1];
cout<<"a->lane["<<i<<"][1]: "<<a->lane[i][1]<<endl;
}
I'd prefer to separate the code for reading data from the code for displaying data. Except for things like homework (or debugging) you rarely want to display lots of raw data as you're reading it. In any case, the reading code should normally reside in the operator>> for that class, and the display code in operator<< for the class.
cout<<"Intersection inserted"<<endl;
This seems to be an outright falsehood. You haven't actually inserted an Intersection into anything.
delete a;
When you quit allocating the Intersection dynamically, you'll be able to eliminate this as well. If you insist on handling all the dynamic allocation by hand, you need to delete the components before this to avoid having memory leaks (another reason to prefer to std::vector).
I know that may sound pretty negative, and that leaves me a bit torn. On one hand, I'd really like to suggest better ways to do things. At the same time, this looks enough like homework that I'm extremely hesitant to just post better code either. I've tried to include a few hints about better ways, but realize they're probably not quite as specific as you'd like -- I apologize for that, but given that it's probably homework I don't think I can be a lot more specific.