C++ read() from ifstream: without pointers? - c++

Suppose I have a struct and a file with binary representations of those structs and I'll make a function/method that access this binary data using ifstream::read().
Here's an example struct:
struct MyStruct {
int x; //Value interested in
int y; //Value interested in
int anotherInteger; //Not interested
double aDouble; //Not interested
}
How do I make the function (I'll call it here readData) either: not using pointers when reading or, if using pointers is necessary, where would I put the proper delete?
So far, the relevant part of my readData looks like this:
void readData(int position, int &returnX, int &returnY) {
ifstream inFile("binaryFile.dat",ios::binary);
MyStruct *st = new MyStruct[1];
inFile.seekg(sizeof(MyStruct)*pos);
inFile.read((char*) st, sizeof(MyStruct));
returnX = st[0].x;
returnY = st[0].y;
//delete [] st goes here?
}
I've tried uncommenting the delete part, but I get an allocation error, probably because the values of x and y are pointing to something that doesn't exist anymore.
Any ideas on how to solve this?

Why wouldn't you use a local variable?
void readData(int position, int &returnX, int &returnY) {
ifstream inFile("binaryFile.dat",ios::binary);
inFile.seekg(sizeof(MyStruct)*position);
MyStruct st;
inFile.read((char*) &st, sizeof(MyStruct));
returnX = st.x;
returnY = st.y;
}
int main() {
int mainx, mainy;
readData(0, mainx, mainy);
return 0;
}
Also, references cannot be re-seated. Therefore the assignment assigns the value to the origional int passed by the calling function. returnX and returnY are not pointed at the local variables. In the code above, the assignment changes mainx and mainy.

The simpler way it's to use a local variable:
void readData(int position, int &returnX, int &returnY) {
ifstream inFile("binaryFile.dat",ios::binary);
MyStruct st;
inFile.seekg(sizeof(MyStruct)*position);
inFile.read((char*)&st, sizeof(MyStruct));
returnX = st.x;
returnY = st.y;
}

The delete[] is fine. If you get an error, it's not because the values of x and y are pointing to something that doesn't exist anymore since their values are just integers and don't point to anything.

Related

A simple question about pointer assignment in c++ function

This is my code, after a = b; in the function, a is still nullptr....
int getBox(int *a) {
int *b = new int;
*b = 3;
a = b;
std::cout << *a;
}
int main() {
int *a = nullptr;
getBox(a);
std::cout << a;
}
I guess it's a very simple problem... Maybe I forgot too much about C++
I'm not sure what you're trying to do, but this row inside the getBox():
a=&b;
Doesn't actually change a in the main, you actually overrides the pointer(the copy that was made by the function), and make it point somewhere else.
You can do something like this(again, I don't see the point) :
int getBox(int ** a){
int *b = new int;
*b=3;
*a=b;
std::cout<<*a;
}
int main(){
int *a= nullptr;
getBox(&a);
std::cout<<a;
}
Let's assume there is some type T. Now here are 3 different kinds of functions:
void f(T a) { // pass by value (this is a copy of the 'a' in main)
a = /* something else */ ;
}
int main() {
T a = /* something */ ;
f(a);
// a is still something
}
void f(T &a) { // pass by reference (this is a reference to the 'a' in main)
a = /* something else */ ;
}
int main() {
T a = /* something */ ;
f(a);
// a is now something else
}
void f(T *a) { // pass by address (this is a pointer to the address the 'a' in main)
*a = /* something else */ ;
}
int main() {
T a = /* something */ ;
f(&a);
// a is now something else
}
Now you can apply this logic to any T you want, such as int, or int*, and the same rules will work. You can try this out with getBox and see the effect of each version, which should help you understand what's going on. Note that you are using the first version (pass by value), but for the result you are expecting, you should use the second version (pass by reference).
If you really want to change what a is pointing to, then you can think it this way maybe it will help to make it a bit easier to understand. A is an int pointer and the function getBox takes a reference that you can modify its value which is an int pointer.
void getBox(int* &a) {
int *b = new int;
*b = 3;
a = b;
std::cout << *a;
}
int main(){
int *a= nullptr;
getBox(a);
std::cout<< *a;
}
This will change the value of a, which is a new pointer value to b.
Yes of course, why should changing a in getBox change the value of a in main? If you think the answer is 'because it's a pointer' then I'm afraid you've misunderstood pointers.
Look at this code
int getBox(int a){
a=3;
std::cout<<a;
}
int main(){
int a= 0;
getBox(a);
std::cout<<a;
}
Setting a=3 in getBox has no effect on a in main. Your code is exactly the same, but for some reason because pointers are involved beginners often think it works differently. It doesn't.
You can however use pointers in this way to change what is being pointed at, that's the important thing, but changing the pointer itself doesn't work in the way you are expecting.
You probably only want to change to getBox(int * & a). You then pass a reference to the pointer a to the function instead of creating a copy of the pointer that points to the same address in your case NULL.

How to return an array of structs from a class in a getter function

I have a relatively simple question but I cant seem to find an answer specific for my case and I just may not be approaching this problem the right way. I have a class that looks like this:
struct tileProperties
{
int x;
int y;
};
class LoadMap
{
private:
ALLEGRO_BITMAP *mapToLoad[10][10];
tileProperties *individualMapTile[100];
public:
//Get the struct of tile properties
tileProperties *getMapTiles();
};
I have an implementation that looks like this for the getter function:
tileProperties *LoadMap::getMapTiles()
{
return individualMapTile[0];
}
I have code in the LoadMap class that will assign 100 tile properties for each struct in the array. I want to be able to access this array of structs in my main.cpp file but I just cant seem to find the right syntax or approach. My main.cpp looks like this.
struct TestStruct
{
int x;
int y;
};
int main()
{
LoadMap _loadMap;
TestStruct *_testStruct[100];
//This assignment will not work, is there
//a better way?
_testStruct = _loadMap.getMapTiles();
return 0;
}
I realize that there are many approaches to this, but I'm trying to keep this implementation as private as possible. If someone could please point me in the right direction I would greatly appreciate it. Thank you!
TestStruct *_testStruct;
_testStruct = _loadMap.getMapTiles();
This will get you a pointer to the first element in the array returned. You can then iterate through the other 99.
I would highly recommend using vectors, or another container, and writing getters that don't return pointers to bare arrays like that.
First of all, here, why do we need TestStruct, you can use "tileProperties" structure itself...
And imp thing,
tileProperties *individualMapTile[100]; is array of pointers to the structure.
Hence, individualMapTile will have pointers in it.
You have returned the first pointer, hence you can access the first structure only. What about the others????
tileProperties** LoadMap::getMapTiles()
{
return individualMapTile;
}
int main()
{
LoadMap _loadMap;
tileProperties **_tileProperties;
_tileProperties = _loadMap.getMapTiles();
for (int i=0; i<100;i++)
{
printf("\n%d", (**_tileProperties).x);
_tileProperties;
}
return 0;
}
Use vectors instead of arrays where possible. Also consider an array/vector of TestStruct directly rather than pointers to them. I can't tell if that would be appropriate for you from your code sample.
class LoadMap
{
public:
typedef vector<tileProperties *> MapTileContainer;
LoadMap()
: individualMapTile(100) // size 100
{
// populate vector..
}
//Get the struct of tile properties
const MapTileContainer& getMapTiles() const
{
return individualMapTile;
}
MapTileContainer& getMapTiles()
{
return individualMapTile;
}
private:
MapTileContainer individualMapTile;
};
int main()
{
LoadMap _loadMap;
LoadMap::MapTileContainer& _testStruct = _loadMap.getMapTiles();
}

Pass an array of wchar by reference

I want to make a function to allocate memory to an array. Suppose I have this:
PWSTR theStrings[] = { L"one", L"two", L"three" };
void foo(PWSTR a, int b) {
a=new PWSTR[b];
for(int i=0;i<b;i++) a[i]=L"hello";
return;
}
int main() {
foo(theStrings,4);
}
My question is, how do you make the function foo and the calling of that function so that after foo is called, theStrings will contain four "hello"
Thanks :)
Reinardus
There are two thing you must do to make this work:
Firstly, you must use a dynamically allocated array, rather than a statically allocated array. In particular, change the line
PSWTR theStrings[] = { L"one", L"two", L"three" };
into
PWSTR * theString = new PWSTR[3];
theString[0] = L"one";
theString[1] = L"two";
theString[2] = L"three";
This way, you're dealing with a pointer which can be modified to point to a different region of memory, as opposed to a static array, which utilized a fixed portion of memory.
Secondly, you're function should take either a pointer to a pointer, or a reference to a pointer. The two signatures look like this (respectively):
void foo(PWSTR ** a, int b); // pointer to pointer
void foo(PWSTR *& a, int b); // reference to pointer
The reference-to-pointer option is nice, since you can pretty much use your old code for foo:
void foo(PWSTR *& a, int b) {
a = new PWSTR[b];
for(int i=0;i<b;i++) a[i]=L"hello";
}
And the call to foo is still
foo(theStrings, 4);
So almost nothing must be changed.
With the pointer-to-pointer option, you must always dereference the a parameter:
void foo(PWST ** a, int b) {
*a = new PWSTR[b];
for(int i = 0; i<b; i++) (*a)[i] = L"hello";
}
And must call foo using the address-of operator:
foo(&theStrings, 4);
PWSTR theStrings[] = { L"one", L"two", L"three" };
void foo(PWSTR& a, int b) {
a=new PWSTR[b];
for(int i=0;i<b;i++) a[i]=L"hello";
return;
}
int main() {
PWSTR pStrings = theStrings;
foo(pStrings,4);
}
But instead of that, consider using std::vector and std::wstring and so on.
Also, anyway, consider using function result (the return) for function results, instead of in/out arguments.
Cheers & hth.,
If you are not required to use PWSTR then you can use std::vector< std::string > or std::valarray< std::string >.
If you want to store unicode strings (or wide characters) replace std::string with std::wstring.
You can see here on how to convert between CString/LPCTSTR/PWSTR to std::string: How to convert between various string types.
probably change it to something like
void foo(PWSTR * a, int b)
and
foo(&thestrings, 4);

Passing pointer to 2D array c++

I'm having this problem for quite a long time - I have fixed sized 2D array as a class member.
class myClass
{
public:
void getpointeM(...??????...);
double * retpointM();
private:
double M[3][3];
};
int main()
{
myClass moo;
double *A[3][3];
moo.getpointM( A ); ???
A = moo.retpointM(); ???
}
I'd like to pass pointer to M matrix outside. It's probably very simple, but I just can't find the proper combination of & and * etc.
Thanks for help.
double *A[3][3]; is a 2-dimensional array of double *s. You want double (*A)[3][3];
.
Then, note that A and *A and **A all have the same address, just different types.
Making a typedef can simplify things:
typedef double d3x3[3][3];
This being C++, you should pass the variable by reference, not pointer:
void getpointeM( d3x3 &matrix );
Now you don't need to use parens in type names, and the compiler makes sure you're passing an array of the correct size.
Your intent is not clear. What is getpointeM supposed to do? Return a pointer to the internal matrix (through the parameter), or return a copy of the matrix?
To return a pointer, you can do this
// Pointer-based version
...
void getpointeM(double (**p)[3][3]) { *p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(&A);
}
// Reference-based version
...
void getpointeM(double (*&p)[3][3]) { p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(A);
}
For retpointM the declaration would look as follows
...
double (*retpointM())[3][3] { return &M; }
...
int main() {
double (*A)[3][3];
A = moo.retpointM();
}
This is rather difficult to read though. You can make it look a lot clearer if you use a typedef-name for your array type
typedef double M3x3[3][3];
In that case the above examples will transform into
// Pointer-based version
...
void getpointeM(M3x3 **p) { *p = &M; }
...
int main() {
M3x3 *A;
moo.getpointM(&A);
}
// Reference-based version
...
void getpointeM(M3x3 *&p) { p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(A);
}
// retpointM
...
M3x3 *retpointM() { return &M; }
...
int main() {
M3x3 *A;
A = moo.retpointM();
}
The short answer is that you can get a double * to the start of the array:
public:
double * getMatrix() { return &M[0][0]; }
Outside the class, though, you can't really trivially turn the double * into another 2D array directly, at least not in a pattern that I've seen used.
You could create a 2D array in main, though (double A[3][3]) and pass that in to a getPoint method, which could copy the values into the passed-in array. That would give you a copy, which might be what you want (instead of the original, modifiable, data). Downside is that you have to copy it, of course.
class myClass
{
public:
void getpointeM(double *A[3][3])
{
//Initialize array here
}
private:
double M[3][3];
};
int main()
{
myClass moo;
double *A[3][3];
moo.getpointM( A );
}
You may want to take the code in your main function which works with the 2D array of doubles, and move that into myClass as a member function. Not only would you not have to deal with the difficulty of passing a pointer for that 2D array, but code external to your class would no longer need to know the details of how your class implements A, since they would now be calling a function in myClass and letting that do the work. If, say, you later decided to allow variable dimensions of A and chose to replace the array with a vector of vectors, you wouldn't need to rewrite any calling code in order for it to work.
In your main() function:
double *A[3][3];
creates a 3x3 array of double* (or pointers to doubles). In other words, 9 x 32-bit contiguous words of memory to store 9 memory pointers.
There's no need to make a copy of this array in main() unless the class is going to be destroyed, and you still want to access this information. Instead, you can simply return a pointer to the start of this member array.
If you only want to return a pointer to an internal class member, you only really need a single pointer value in main():
double *A;
But, if you're passing this pointer to a function and you need the function to update its value, you need a double pointer (which will allow the function to return the real pointer value back to the caller:
double **A;
And inside getpointM() you can simply point A to the internal member (M):
getpointeM(double** A)
{
// Updated types to make the assignment compatible
// This code will make the return argument (A) point to the
// memory location (&) of the start of the 2-dimensional array
// (M[0][0]).
*A = &(M[0][0]);
}
Make M public instead of private. Since you want to allow access to M through a pointer, M is not encapsulated anyway.
struct myClass {
myClass() {
std::fill_n(&M[0][0], sizeof M / sizeof M[0][0], 0.0);
}
double M[3][3];
};
int main() {
myClass moo;
double (*A)[3] = moo.M;
double (&R)[3][3] = moo.M;
for (int r = 0; r != 3; ++r) {
for (int c = 0; c != 3; ++c) {
cout << A[r][c] << R[r][c] << ' ';
// notice A[r][c] and R[r][c] are the exact same object
// I'm using both to show you can use A and R identically
}
}
return 0;
}
I would, in general, prefer R over A because the all of the lengths are fixed (A could potentially point to a double[10][3] if that was a requirement) and the reference will usually lead to clearer code.

Accessing Function Variable After calling it while Being in main()

I want to access variable v1 & v2 in Func() while being in main()
int main(void)
{
Func();
int k = ? //How to access variable 'v1' which is in Func()
int j = ? //How to access variable 'v2' which is in Func()
}
void Func()
{
int v1 = 10;
int v2 = 20;
}
I have heard that we can access from Stack. But how to do.
Thank you.
You can't legally do that. Automatic variables disappear once execution leaves the scope they're declared in.
I'm sure there are tricks, like inspecting the stack and going "backwards" in time, but all such tricks are platform-dependent, and might break if you, for instance, cause the stack to be overwritten in main().
Why do you want to do that? Do you want those values as return values? I would introduce a struct for that, according to the meaning of the values the struct would get a suitable name
struct DivideResult {
int div;
int rem;
};
DivideResult Func() {
DivideResult r = { 10, 20 };
return r;
}
int main() {
DivideResult r = Func();
}
Otherwise, such variables are for managing local state in the function while it is activated. They don't have any meaning or life anymore after the function terminated.
Some ways you can do this are:
Declare the variables in main() and pass them by pointer or reference into Func()
Return the variable, or vector< int >, or a struct that you made, etc. of the variables to main()
Dynamically allocate the variables in Func(), and return a pointer to them. You would then have to remember to delete the allocated memory later as well.
But there is no access to the stack of Func() from main() that is standard.
You can't do that portably. When Func()'s stack frame disappears, there's no reliable way to access it. It's free to be trampled. However, in x86-64, there is something known as the red zone, which is a 128B area below the stack pointer that is safe from trampling, and theoretically you might still be able to access it, but this is not portable, easy, nor correct. Simply put, don't do it.
Here's how I would do it:
int main(void)
{
int k, j;
Func(&k, &j);
}
void Func(int *a, int *b)
{
*a = 10;
*b = 20;
}
You're in C/C++ land. There are little you cannot do.
If this your own code, you shouldn't even try to do that. Like others suggested: pass a output parameter by reference (or by pointer in C) or return the values in a struct.
However, since you asked the question, I assume you are attempting to look into something you only have binary access to. If it is just an one time thing, using a debugger will be easier.
Anyway, to answer your original question, try the following code. You have to compile it in for x86 CPU, with optimization and any stack debug flag turned off.
void f() {
int i = 12345;
int j = 54321;
}
int main()
{
int* pa = 0;
int buf[16] = {0};
f();
// get the stack pointer
__asm {
mov dword ptr [pa],ESP
}
// copy the stack, try not to do anything that "use" the stack
// before here
for (int i = 0; i < 16; ++i, --pa) {
buf[i] = *pa;
}
// print out the stack, assuming what you want to see
// are aligned at sizeof(int)
for (int i = 0; i < 16; ++i) {
std::cout << i << ":" << buf[i] << std::endl;
}
return 0;
}