A simple question about pointer assignment in c++ function - c++

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.

Related

function definition in C++ [duplicate]

I understand the concept of references in C++, and I understand what they do when used in function parameters, but I am still very much confused on how they work with return types.
For example, when used in parameters, this code:
int main (void) {
int foo = 42;
doit(foo);
}
void doit (int& value) {
value = 24;
}
is similar to this code:
int main (void) {
int foo = 42;
doit(&foo);
}
void doit (int* value) {
*value = 24;
}
(knowing that the compiler will automatically put an asterisk in front of value every time it is used in the first code sample of doit, but in the latter you'd have to put the asterisk in yourself every time you try to use value)
So when used as a reference what does this next code (using reference in a return type) translate to? Does it return a pointer to an int? Or would it just return an int?
int main (void) {
int* foo = /*insert useful place in memory*/;
foo = doit(foo);
}
int& doit (int* value) {
//insert useful code
}
It means you return by reference, which is, at least in this case, probably not desired. It basically means the returned value is an alias to whatever you returned from the function. Unless it's a persistent object it's illegal.
For example:
int& foo () {
static int x = 0;
return x;
}
//...
int main()
{
foo() = 2;
cout << foo();
}
would be legal and print out 2, because foo() = 2 modifies the actual value returned by foo.
However:
int& doit () {
int x = 0;
return x;
}
would be illegal (well, accessing the returned value would), because x is destroyed when the method exits, so you'd be left with a dangling reference.
Returning by reference isn't common for free functions, but it is for methods returning members. For example, in the std, the operator [] for common containers return by reference. For example, accessing a vector's elements with [i] returns an actual reference to that element, so v[i] = x actually changes that element.
Also, I hope that "is essentially equal to this code" means that they're semantically sort of (but not really) similar. Nothing more.
It means that you return a pointer to the memory address where the correspondent data is, instead of the very data.
Assuming this code (to make it comparable to the first example) :
int main (void) {
int* foo = /*insert useful place in memory*/;
*foo = doit(foo);
}
int& doit (int* value) {
*value = 24;
return *value;
}
The int& is not really useful as a return type in this case, because it provides access to the variable in memory (of which you pass the pointer to the function).
Does it return a pointer to an int? Or would it just return an int?
No, it returns a reference to an int. If you want, you can look at it as a pointer which can not be nullptr.
Hmm, the best way to know the answer is to have a try...
Your codes will not pass type check, because doit will return a reference of int while you accept the return value as a pointer of int.
You can have a look at this:
#include<iostream>
using namespace std;
int& doit (int* value) {
value[0] = 3;
return value[4];
}
int main (void) {
int* foo = new int[10];
for (int i=0; i<10; i++)
foo[i] = i;
int& bar = doit(foo);
cout<<bar<<endl;
for (int i=0; i<10; i++)
cout<<foo[i]<<" ";
cout<<endl;
bar = 12;
for (int i=0; i<10; i++)
cout<<foo[i]<<" ";
cout<<endl;
return 0;
}
The variable "bar" will accept the return value, and it can be used change the content of "foo". As is mentioned by Luchian, it maybe dangerous to return a reference from the function, because the later codes might modify a value which is in the stack.

deleting reference to dereferenced int

Even though the following piece of code compiles and runs fine i want to know if it is a valid c++ code?
int main()
{
int *i= new int;
cout<<*i;
int &ref=*i;
cout<<ref;
delete &ref; //Especially is this statement valid?
return 0;
}
If it is valid then this must also be valid :
int& getInt() {
int* i = new int;
return *i; // OK?
}
int main(){
int& myInt = getInt(); // these two lines are same as shown in the example above ?
delete &myInt; //is this OK too?
}
It's correct code and it will work on all platforms and compilers.
However, it's probably not best practice as the reference is usually used when the called party retains the ownership of the object.

Assigning pointer to a different address in function

just curious what is the explanation of this?
void f(int * x);
int test = 100;
int main()
{
int z = 35;
int * a = &z;
f(a);
cout<<*a;
..
}
void f(int *x)
{
x = &test;
}
We are taught we can use pointers inside function arguments if we want to modify the "outside" object (as a in this case). But x = &test does not do much, and the cout still prints 35.
I know *x =someVal would work though in f().
In C pointers are passed by value just like ints, floats, etc. So if you want to modify it and have that modification be visible outside of the function call, you need to pass a pointer to the thing you want to modify, in this case that's a pointer to a int pointer:
void f(int **x) {
*x = &test;
}
However, in C++ passing a reference is a much better approach:
void f(int*& x) {
x = &test;
}
If you labeled the question C, what you taught it would be acceptable. For C++ it is techically correct but morally wrong, you should pass by reference to modify the object, not fiddling with pointer and address.
In your code you get what you coded for: pass a pointer and then reassign that poitner's value. That is not visible outside the function. What you intended to do is
void f(int *x)
{
*x = 42;
}
and the C++ version would be like:
void f(int &x)
{
x = 42;
}
int main()
{
int z = 35;
f(z);
cout << z;
}
Due to recommendation of one of the members I am adding my own answer which I derived from the other peoples responses. So thanks go to them.
Basically the problem in my code was that I was changing a copy of my pointer.
The only thing x in function f and the value a passed to f have in common is the address where they point to.

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;
}