Why am I Able to Make a Function Call Using an Invalid Class Pointer

Why am I able to make a function call using an invalid class pointer

The C++ compiler doesn't prevent you from using uninitialised pointers, and although the results are undefined, it's normal for compilers in the real world to generate code that ignores the fact that the pointer is uninitialised.

It's one of the reasons why C++ is both fast and (comparatively) dangerous relative to some other languages.

The reason your call to func2 succeeds is that it doesn't touch its this pointer. The pointer value is never used, so it can't cause a problem. In func1 you do use the this pointer (to access a member variable), which is why that one crashes.

Calling class method through NULL class pointer

Under the hood most compilers will transform your class to something like this:

struct _ABC_data{  
int a ;
};
// table of member functions
void _ABC_print( _ABC_data* this );

where _ABC_data is a C-style struct
and your call ptr->print(); will be transformed to:

_ABC_print(nullptr)

which is alright while execution since you do not use this arg.


UPDATE: (Thanks to Windows programmer for right comment)

Such code is alright only for CPU which executes it.

There is absolutely positively no sane reason to exploit this implementation feature. Because:

  1. Standard states it yields undefined behavior
  2. If you actually need ability to call member function without instance, using static keyword gives you that with all the portability and compile-time checks

Pointer to a class method call

cannot convert from 'void (__cdecl *)(RationalNumber &)' to 'RationalNumber::pointer_to_f'

on the line

pointer_to_f p = &simplification;

Let's see what we have here. This line initializes a variable (p) of type RationalNumber::pointer_to_f, which corresponds with what the attempted conversion is to. On the right-hand side of the = is the address of RationalNumber::simplification, a static member function from RationalNumber& to void. Check, that matches the error message.

So the first error comes down to the fact that a pointer to member function must point to a non-static member function. The address of a static member function is a normal function pointer (largely because it lacks the hidden this parameter).

Given your setup, it seems to make sense to remove the static keyword from simplification as well as removing its parameter. Have it operate on *this, which becomes available once the member function is no longer static.

Alternatively, you could change your pointers to member functions into regular pointers to functions, if for some reason simplification needs to be static. (Given that the function needs a RationalNumber object in either case, I don't see why static would be desirable.)


The remaining errors are technically independent, but I'll throw in some that have to do with invalid use of a pointer to member function.

callback((p)(this));

This invokes the function pointed to by p and supplies the pointer this as an argument. The returned value (void) becomes the argument to callback. If you want to pass p as the argument to callback, then pass p:

callback(p);

void RationalNumber::callback(pointer_to_f *p(RationalNumber& x) )

This does not match the declaration. You declared callback as a function whose parameter is a pointer_to_f. This definition has a parameter whose type is a function taking a RationalNumber& parameter and returning a pointer_to_f (the x is meaningless here). Be consistent!

void RationalNumber::callback(pointer_to_f p)

If you want to pass in something to use as the argument when p is invoked, you would need a second parameter. See also Function pointer to member function for how to fix the syntax you use to invoke p.


Final note: using a callback here looks like serious over-engineering, but I suppose the need for it might exist in details removed to make the example code simple.

function pointers generate 'invalid use of non-static member function' error

The syntax to declare a function pointer to member methods is:

int (A::*plus)(int, int) = &A::add;
int (A::*minus)(int, int) = &A::subtract;

To invoke member methods use .* or ->* operator:

 (a_plus.*plus)(7, 5);

Also have a look at http://msdn.microsoft.com/en-us/library/b0x1aatf(v=vs.80).aspx

Hope this helps.

Complete code:

     #include <iostream>

using namespace std;

class A
{
public:
int add(int first, int second)
{
return first + second;
}

int subtract(int first, int second)
{
return first - second;
}

int operation(int first, int second, int (A::*functocall)(int, int))
{
return (this->*functocall)(first, second);
}
};

int main()
{
int a, b;
A a_plus, a_minus;
int (A::*plus)(int, int) = &A::add;
int (A::*minus)(int, int) = &A::subtract;
a = a_plus.operation(7, 5, plus);
b = a_minus.operation(20, a, minus);
cout << "a = " << a << " and b = " << b << endl;
return 0;
}

C++: Invalid use of abstract class inside pointer vector when calling member functions

You need to include GameState.hpp into Game.cpp so GameState will be complete at that point. Forward declaration allows to declare std::stack<GameState*> however a definition should be available to call class methods.

Invalid pointer calling destructor on pointer to object containing std::string

Your problem is in the ECSComponentFree() function where you call the destructor manually:

template<typename Component>
void ECSComponentFree(BaseECSComponent* comp)
{
Component* component = (Component*)comp;
component->~Component(); //call the destructor
}

And when your object goes out of scope, the destructor is called again which tried to free the memory again resulting in double free.

You can understand it better by running the following simple example Try Live:

class A {
std::string* s = new std::string{"Hello"};
public:
A() { printf("ctor\n"); }
void freee() { printf("freeing\n"); this->~A(); }
~A() { delete s; printf("dtor\n"); }
};

int main()
{
A a;
a.freee();
return 0;
}

Type conversion error in pointer to class member function

You've indeed encountered pointers to member functions. They're similar to ordinary function pointers, but more nuanced, because (non-static) member functions always implicitly have a special this parameter passed to them that refers to the current object on which the function was invoked. That secret this parameter is strongly typed according to the class containing the function. That's why the class name is also part of a pointer to member function's type. It's also the reason they don't mix with regular function pointers. Here's a basic example:

// Declaration of a pointer to member function
// Note that no object is used here
void (ClassName::*my_fn_pointer)(ParameterTypes);

// Assignment also doesn't use an object
my_pointer = &ClassName::exampleMemberFunction;

// But to invoke the method, you need an object
ClassName obj;
(obj::*my_fn_pointer)(example_params);

// Alternatively, inside a member function of ClassName:
(this->*my_fn_pointer)(example_params);

There are plenty of alternatives. I can't see the rest of your code and what problem you're trying to solve and so my advice is limited. I would however endorse using std::function with lambdas:

// std::function generically wraps a callable type
std::function<void(ParamTypes)> my_fn;

// Using an object:
ClassName obj;
// lambda declaration
my_fn = [&obj](ParamTypes params){
// 'obj' is captured by reference, so make sure it stays alive as long as needed
obj.chooseYourMemberFunctionHere(params);
};

// function is called here, syntax is easier on the eyes
my_fn(example_params);

// Using 'this' inside a member function:
my_fn = [this](ParamTypes params){
// 'this' is captured by reference
// also make sure the current object stays alive alive as long as needed
this->chooseYourMemberFunctionHere(params);
};

my_fn(example_params); // function is called here

Is it possible to call a method pointer with a void* pointer to the object

Is it possible to call a method pointer with a void* pointer to the object

No, it is not. More generally, you cannot indirect through a pointer to void at all.

Pointer to void must be casted to an pointer to object type that is compatible with the pointer to member function.

I don't (and can't) have information of that objects' class

If you know that the type of the object is compatible with the pointer to member function, then you should know what that type is. If you don't know the type, then you don't know that it's compatible and thus cannot call the pointer to member function.

Why do I get an invalid pointer when freeing a pointer to a struct in C

int pHeight = 2000; 

(*plane).height = malloc(sizeof(int));
if ((*plane).height == NULL) {
free(plane);
printf("ALLOCATE MEMORY FAILURE, plane->length\n");
exit(1);
}

plane->height = &pHeight;

free(plane->height)
  1. You allocate memory for a int and make height point to this memory.

  2. You then you make height point to pHeight which is a variable with automatic storage duration. This as a result leads to a memory leak since the memory you malloc()'d is now lost.

  3. You then call free() on height, which is pointing to memory that isn't from malloc(), calloc() or realloc(), so using free() on it is invalid.

The free() man page says:

void free(void *ptr);
The free() function frees the memory
space pointed to by ptr, which must
have been returned by a previous call
to malloc(), calloc() or realloc().


Related Topics



Leave a reply



Submit