#include <iostream>
#include <vector>
using namespace std;
class Foo
{
public:
virtual void f1()
{
cout << "Foo::f1()" << endl;
}
virtual void f2()
{
cout << "Foo::f2()" << endl;
}
virtual void f3()
{
cout << "Foo::f3()" << endl;
}
};
int main()
{
typedef void(*MethodFoo_f)();
Foo* ptr = new Foo();
cout << "Object address: " << ptr << endl;
cout << "__vfptr: " << (int*)*((int*)ptr) << endl;
for(int i = 0; i < 3; ++i)
{
int* e = (int*)*((int*)ptr) + i;
cout << "Address from __vfptr " << e;
auto t = &Foo::f1;
switch(i)
{
case 0: t = &Foo::f1; cout << ", address from main " << (void*&)t << " "; break;
case 1: t = &Foo::f2; cout << ", address from main " << (void*&)t << " "; break;
case 2: t = &Foo::f3; cout << ", address from main " << (void*&)t << " "; break;
}
cout << "execute: ";
auto func = (MethodFoo_f*)(e);
(*func)();
}
}
Hi all, can you explain me: why we can see difference in addresses of same method's.
Example output for Visual Studio
Object address: 007ADE28
__vfptr: 00E63B34
Address from __vfptr 00E63B34, address from main 00E51F23 execute:
Foo::f1()
Address from __vfptr 00E63B38, address from main 00E51F1E execute:
Foo::f2()
Address from __vfptr 00E63B3C, address from main 00E51F19 execute:
Foo::f3()
If VTABLE call transforme to
objPointer->(__vfptr + methodIndex)()
Why in table, we hold modified values of addresses ?
I finally realized what you wanted, you are missing one level of indirection.
ptr points to the object
(assuming 32 bit and many other things you shouldn't really assume):
*((int*)ptr) is the address of the vtable
(int*)*((int*)ptr) is *((int**)ptr) is a cast of that same address
(int*)*((int*)ptr)+i is & (*((int**)ptr))[i] is a position within the vtable and you wanted the contents of that position:
*((int*)*((int*)ptr)+i) or (*((int**)ptr))[i]
You have that extra level of indirection instead in func
MethodFoo_f is the type of a pointer to the function and func is a pointer to MethodFoo_f
So the numbers you expect to be the same for each function were a pointer to pointer to function and a simple pointer to function.
I still wouldn't guess the pointer to function you get from auto t = &Foo::f1; reliably has the same contents as a void* to the actual code of the function. But at least with the correct levels of indirection you would be comparing it to that.
Related
I'm a python programmer new to C++. Currently getting a segfault when trying to play around with pointers. Can someone explain this behavior? I suspect there's something significant about cout that I'm not understanding.
#include<iostream>
using namespace std;
int main() {
int var; // declaration
cout << "var declared" << endl;
cout << "var : " << var << endl;
cout << "&var : " << &var << endl;
var = 10; // initialization
cout << "\nvar initialized" << endl;
cout << "var : " << var << endl;
cout << "&var : " << &var << endl;
int* ptr; // declaration
cout << "\nptr declared" << endl;
cout << "ptr : " << ptr << endl;
cout << "*ptr : " << *ptr << endl;
cout << "&ptr : " << &ptr << endl;
ptr = &var; // initialization
cout << "\nptr initialized : " << endl;
cout << "ptr : " << ptr << endl;
cout << "*ptr : " << *ptr << endl;
cout << "&ptr : " << &ptr << endl;
return 0;
}
using this compiler command
g++ --std=c++14 main.cpp -o main_exec;
This code produces the following output
var declared
var : 0
&var : 0x7fff55724478
var initialized
var : 10
&var : 0x7fff55724478
ptr declared
ptr : 0x0
[1] 82727 segmentation fault ./main_exec
This code obviously compiles but produces a segfault at runtime.
Things I've tried
I've tried combinations of commenting out the lines that include *ptr and the lines that include &ptr, short story is some combinations produce no segfault. It seems that I can use *ptr 1 time and not in combination with &ptr
You declared a pointer to an integer, but not initialized or assigned it with any pointer (i.e. to memory address of an integer variable).
int* ptr; // declaration
The line above says, ptr is a pointer (that would point to memory address of an integer variable). In your case it just says it is a pointer, what it does point is not defined.
When you hit this line,
cout << "*ptr : " << *ptr << endl;
Here *ptr means, get the value at address (the address that actually would store the value) and is being pointed by ptr. However ptr points to nothing. So you're trying to access memory in a way that is not permitted which leads to the segmentation fault.
Just remember that pointers are variable that as their values store memory address of another variable.
int *ptr; // would store memory address of an integer type variable.
int a = 5; // would store an integer variable.
ptr = &a; // Here &a gets the address of variable a and stores in *ptr
cout<<*ptr // Here *ptr gets the value of variable whose memory address is pointed to by *ptr.
Edit
To answer the question if int * ptr = new int; is valid.
Yes it will reserve you a memory location and allows you to later store values on that location later, as shown in code below,
int* ptr = new int; // gets memory address and assigns to *ptr
*ptr = 5; // assigns value 5 to the memory being pointed by *ptr
cout<<*ptr; // output 5
However you're supposed to not do this unless you've a particular need.
Variables reserve you memory, and give you a friendly variable name of your choice.
Anything you create with new is not deleted automatically, as suggested in comment section.
Variables, in contrast to this, are deleted automatically when they get out of scope (block, function, loop, etc.)
I am new to c++, and there is a problem that I find cannot directly output the address of return.
when I run test03() it occurs a error like below. But test04() works fine.
C102:"&"要求左值
in English it should mean
C102:& needs a left value
I have put script below, I think the return will be free if it not be used. But hope for a concrete answer.
int change(int a) {
return --a;
}
void test03() {
int a = 10;
cout << "the first address is " << &a << "the later adress is " << &(change(a)) << endl;
}
void test04() {
int a = 10;
int b = change(a);
cout << "the first address is " << &a << "the later adress is " << &b << endl;
}
int main(){
test04();
return 0;
}
This question already has an answer here:
C++ parameter passing queries (code examples and outputs included)
(1 answer)
Closed 8 years ago.
First of all, i have no idea how to word the title whilst keeping it descriptive if anybody has a better idea feel free to edit.
My question is as follows; I have been given a set of function definitions and calls to these functions which currently operate using an int* as the variable that is being passed in various ways to these functions.
My task is to without changing the function definitions make the program compile and produce the same output but this time use an int over an int*.
Desired output:
Result
first 43
second 43
third 44
fourth 0
fifth 69
This is the code for the when the variable is an int*
void MyIncrementFirst(int* i) {
(*i)++;
}
void MyIncrementSecond(int i) {
i++;
}
void MyIncrementThird(int & i) {
i++;
}
void MyIncrementFourth(int** i) {
*i = new int(0);
}
void MyIncrementFifth(int*& i) {
i = new int(69);
}
int main(){
int* a = new int(42);
cout << "Result" << endl;
MyIncrementFirst(a);
cout << "first " <<*a << endl;
MyIncrementSecond(*a);
cout << "second " <<*a << endl;
MyIncrementThird(*a);
cout << "third " <<*a << endl;
MyIncrementFourth(&a);
cout << "fourth " <<*a << endl;
MyIncrementFifth(a);
cout << "fifth " <<*a << endl;
return 0;
}
Now here is what i have so far when changing the type of a to an int, not an int*:
Note: The function definitions are the same as above.
int main(){
int a = 42;
cout << "Result" << endl;
MyIncrementFirst(&a);
cout << "first " <<a << endl;
MyIncrementSecond(a);
cout << "second " <<a << endl;
MyIncrementThird(a);
cout << "third " <<a << endl;
/*
MyIncrementFourth(&a);
cout << "fourth " <<a << endl;
MyIncrementFifth(a);
cout << "fifth " <<a << endl;
*/
return 0;
}
Which prints:
Result
first 43
second 43
third 44
Calls to MyIncrementFourth and MyIncrementFith have been commented because i am not sure how to translate this to handle an int rather than an int*. Any attempts i do would just be fluke rather than knowledge.
Can anybody help me identify how to correctly complete the calls to MyIncrementFourth and MyIncrementFith in order to achieve a correct result.
Thanks,
Chris.
void foo(int a) {
...
}
int main() {
int a = 5;
foo(a);
return 0;
}
While with * it would be like this
void foo(int* a) {
...
}
int main() {
int a = 5;
foo(&a);
return 0;
}
However, this reminds of C.
You could use the & operator, instead of the *, like this:
void foo(int& a) {
...
}
int main() {
int a = 5;
foo(a);
return 0;
}
I assume you know what passing by value and by reference means. If you want a refresh, take a look in my example here.
[EDIT]
Also note that the code in the first block of yours is not OK, since you call new twice, but you never call delete.
Also, about what you are asking, you cannot do it without using an extra pointer. In other words, it can not be done by only having int a in the play.
Example:
int* a_pointer = &a;
MyIncrementFourth(&a_pointer);
cout << "fourth " << a << ", but a_pointer points to " << *a_pointer << endl;
Why the value of a did not change, despite the fact that we set the a_pointer to be equal with the address of a.
Because inside your function, you are calling new and as you know, it will return a pointer to the new allocated memory.
As a result, a_pointer is assigned a new value. Which value? The address of the new allocated memory.
When you use
int a = 42;
instead of
int* a = new int(42);
fourth and fifth function can't be used. The MyIncrementFourth and MyIncrementFifth (counterintuitive names, by the way) pretend to replace the pointer you allocated in the main with another pointer to another area, allocated inside the functions (and there will be a memory leak since you no longer will be able to delete the original a…). But if you stick to int a = 42 instead of int* a = new int(42), your variable is not a pointer, thus those functions have no pointer they can replace.
You can use:
int* ap = &a;
MyIncrementFourth(&ap);
MyIncrementFifth(ap);
// These calls change what ap points to.
// It does not change the value a.
You can also use:
int* ap = NULL;
MyIncrementFourth(&ap);
MyIncrementFifth(ap);
// These calls change what ap points to.
int* ptr;
MyIncrementFourth(&ptr);
a = *ptr;
delete ptr;
std::cout << "fourth " << a << std::endl;
MyIncrementFifth(ptr);
a = *ptr;
delete ptr;
std::cout << "fifth " << a << std::endl;
I'm trying to store a lambda in an object system involving several layers of indirection. I'm using g++ 4.7.1.
Depending on how exactly I construct the (equivalent) objects, the lambda may or may not have the correct value.
Code:
#include <iostream>
#include <functional> // used for std::function
using namespace std; // TODO nope
typedef function<int()> intf;
struct SaveLambda {
const intf func;
SaveLambda(const intf& _func) : func(_func) {}
};
struct StoreSaved {
const SaveLambda* child;
StoreSaved(const SaveLambda& _child) : child(&_child) {
cout << "Before returning parent: " << child->func() << endl;
}
};
int main() {
const int ten = 10;
auto S = SaveLambda([ten](){return ten;});
cout << "No indirection: " << S.func() << endl << endl;
auto saved = StoreSaved(S);
cout << "Indirection, saved: " << saved.child->func() << endl << endl;
auto temps = StoreSaved ( SaveLambda([ten](){cout << "&ten: "<< &ten << endl; return ten;}) );
cout << "***** what. *****" << endl;
cout << "Indirection, unsaved: " << temps.child->func() << endl;
cout << "***** what. *****" << endl << endl;
cout << "ten still lives: " << ten << endl;
}
Compile as g++ -std=c++11 -Wall -o itest itest.cpp and run: notice the one line of output with a different value.
What am I doing wrong? I assumed that capture-by-value would, well, capture by value. (Observe most disconcertingly that the print in StoreSaved (line 15) produces the correct value, unlike line 34, despite these both referring to the same object. The only difference is adding another layer of indirection.)
This is wrong:
auto temps = StoreSaved(
/* This temporary value dies at the last semicolon! */
SaveLambda([ten](){cout << "&ten: "<< &ten << endl; return ten;})
);
StoreSaved then has a pointer to a nonexistent object. Using it is UB.
As already pointed out by others, the problem is that in temps you end with a pointer to a nonexistent SaveLambda struct, as it is a temporary.
You can keep a copy using a SaveLambda struct in StoreSaved, instead of a pointer:
struct StoreSaved {
const SaveLambda child;
StoreSaved(const SaveLambda& _child) : child(_child) {
cout << "Before returning parent: " << child.func() << endl;
}
};
You also have to change all the child->func() to child.func(), as you are not dealing with a pointer anymore.
Every time I try to compile my code I get error:
cannot convert parameter 1 from 'int *' to 'int *&'
The test code looks like this:
void set (int *&val){
*val = 10;
}
int main(){
int myVal;
int *pMyVal = new int;
set(&myVal); // <- this causes trouble
set(pMyVal); // <- however, this doesn't
}
I'd like to call that function in a single shot without creating a pointer somewhere only to pass it. And as pointers don't have constructors, something like this can't be done: set(int*(&myVal));
Is there any other way to pass a pointer by reference without needing to create a temporary variable?
Edit: By the way I know why the code fails to compile (I'm just passing the address which is possibly int and not an actual pointer). The question is how else can it be done.
A reference to non-const cannot bind to an rvalue. The result of the & operator is an rvalue. Take a look at the difference between lvalues and rvalues or read a good C++ book.
Also, in your context, you don't need to pass by reference. The following is OK as well:
void set (int *val){
*val = 10;
}
The reference would be needed if you were to do something like this;
void set (int*& val){
val = new int; //notice, you change the value of val, not *val
*val = 10;
}
&myval is an rvalue (of type int*), because it's a temporary. It's a pointer, but you cannot modify it, because it's just created on the fly. Your function set however requires a non-const reference, so you cannot pass it a temporary.
By contrast, pMyVal is a named variable, thus an lvalue, so it can be passed as a non-constant reference.
A very simple example can be found in this place.
http://markgodwin.blogspot.de/2009/08/c-reference-to-pointer.html
You can see the following sample code:
#include <iostream>
using namespace std;
void change(int*& ptr) {
cout << endl;
cout << "==================change(int*& ptr)====================" << endl;
cout << " &ptr = " << &ptr << endl;
cout << " ptr = " << ptr << endl;
cout << "=======================================================" << endl;
cout << endl;
*ptr *= *ptr;
}
int main(void) {
int* ptrNumber = new int(10);
cout << endl;
cout << "&ptrNumber = " << &ptrNumber << endl;
cout << "ptrNumber = " << ptrNumber << endl;
cout << ">>> *ptrNumber = " << *ptrNumber << endl;
change(ptrNumber);
cout << "<<< *ptrNumber = " << *ptrNumber << endl;
}
I installed Cygwin and used g++ to compile the above source code, binary file is out_pointer.exe.
Executing out_pointer.exe, output is as follows:
$ ./out_pointer.exe
&ptrNumber = 0x28ac3c
ptrNumber = 0x800102c0
>>> *ptrNumber = 10
==================change(int*& ptr)====================
&ptr = 0x28ac3c
ptr = 0x800102c0
=======================================================
<<< *ptrNumber = 100
From the above output, we see
&ptrNumber = &ptr
So, ptr is alias of ptrNumber. You can modify ptrNumber inside function void change(int*& ptr) by modifying ptr. For example, you can point ptr to another memory location as below:
#include <iostream>
using namespace std;
void change(int*& ptr) {
cout << endl;
cout << "==================change(int*& ptr)====================" << endl;
cout << " &ptr = " << &ptr << endl;
cout << " >>> ptr = " << ptr << endl;
ptr = new int(20);
cout << " <<< ptr = " << ptr << endl;
cout << "=======================================================" << endl;
cout << endl;
}
int main(void) {
int* ptrNumber = new int(10);
cout << endl;
cout << ">>> &ptrNumber = " << &ptrNumber << endl;
cout << ">>> ptrNumber = " << ptrNumber << endl;
cout << ">>> *ptrNumber = " << *ptrNumber << endl;
change(ptrNumber);
cout << "<<< &ptrNumber = " << &ptrNumber << endl;
cout << "<<< ptrNumber = " << ptrNumber << endl;
cout << "<<< *ptrNumber = " << *ptrNumber << endl;
}
New output:
$ ./out_pointer.exe
>>> &ptrNumber = 0x28ac3c
>>> ptrNumber = 0x800102c0
>>> *ptrNumber = 10
==================change(int*& ptr)====================
&ptr = 0x28ac3c
>>> ptr = 0x800102c0
<<< ptr = 0x80048328
=======================================================
<<< &ptrNumber = 0x28ac3c
<<< ptrNumber = 0x80048328
<<< *ptrNumber = 20
The problem is, int*&val can only be passed an lvalue, which the result of &myVal is not. By changing the signature to void set(int* const& val), it's telling the compiler you're not going to change the value of the pointer.
However, you normally wouldn't do that, only because if you're not going to change the value of the pointer, then passing the pointer by value is the most straightforward way to pass the value. And if you are going to change the value of the pointer, then you need to create a temporary to receive the result.