Two pointer related questions - c++

I am looking to understand the following two pieces of code. I am not proficient in C++ and pointers and the operations which can be used with them are still a little unclear to me.
First piece of code
I have trouble understanding what this function actually does. It takes an unsigned char pointer and returns one as well. But the way I currently see it, it just returns a pointer that points to the same place as the original. I might very well be wrong though.
unsigned char* MemoryPool::GetNext(unsigned char* pBlock)
{
unsigned char** ppChunkHeader = (unsigned char**)pBlock;
return ppChunkHeader[0];
}
Edit: I made an attempt at improving the quality of my formatting and clarifying my problems. I appreciate your helpful comments and answers.
Second piece of code
I know that this is a typedef that aliases (would that be a correct term?) a function pointer as under the type name ActorComponent. But what does the function pointer's function type return? If function pointer syntax is:
void (*foo)(int);
Then what is the meaning of the asterisk before the parentheses in the following line of code?
typedef ActorComponent *(*ActorComponentCreator)(void);

It looks to me like the first one doesn't do much. It casts the passed in pointer to unsigned char to be a pointer to pointer to char (a dangerous and old c style cast at that). Then it uses the fact that an array dereference acts like a pointer dereference to return the original pointer to an unsigned char.
typedef ActorComponent *(*ActorComponentCreator)(void);
Creates a function pointer. In this case ActorComponentCreator is the name that refers to a pointer to a function that takes a void and returns a pointer to an ActorComponent.

If we look at this:
typedef ActorComponent *(*ActorComponentCreator)(void);
and change it around a little:
typedef ActorComponent* (*ActorComponentCreator)(void);
it becoems much clearer that it's a function pointer to a function that returns a pointer to an ActorComponent.
Compare with:
typedef int* (*FuncReturningInt)(void);

The first code is given an unsigned char * (treating approximately as if it was a void *; is the code very old, or based on very old software), converts it to a pointer to a pointer to an unsigned char, and then returns the zeroth unsigned char *. So, it treats the location it is passed as if it was the start of an array of unsigned char * values, and returns the zeroth item in that array. In C++, this is not very good code; it would be more respectable as C code.
The second code declares a pointer to function type named ActorComponentCreator. The function returns an ActorComponent *; the function takes no arguments.

Related

Defining function/method param as pointer and passing without reference

I have a question regarding pointers/references, I couldn't find much information about, so, having this method declaration (C++):
void RequestParser::parseRequest(const char * request)
When I want to use this method, I can call it like this:
requestParser.parseRequest(buffer);
So, going back to the definition the parameter expects a pointer (const char * request), why am I allowed to pass buffer without the reference, this way:
requestParser.parseRequest(&buffer);
This should be the correct way, right? Maybe there is some magic going on behind the scenes, like this:
void RequestParser::parseRequest(const char request[])
I know that you can't pass array as value (at least char arrays), so this is only syntactic sugar for this:
void RequestParser::parseRequest(const char * request)
What am I misunderstanding?
When you pass an array like buffer to parseRequest, array-to-pointer decay occurs,
There is an implicit conversion from lvalues and rvalues of array type to rvalues of pointer type: it constructs a pointer to the first element of an array. This conversion is used whenever arrays appear in context where arrays are not expected, but pointers are:
So you're passing the pointer to the 1st element of the array in fact, it's of type char * (and could convert to const char*).
On the other hand, you can't pass &buffer, which is taking the address of the array and returns the pointer to the array (i.e. char (*)[2048]), it doesn't match the parameter type const char*.

What is the difference between these two casts?

I have a function in my c++ application that needs an integer as an input. Sadly this integer is only available in form of an usigned char array, which inclines me to do this:
unsigned char c[4] = {'1','2','3','4'};
void myFuncThatBadlyNeedsInts(int i)
//compares some memory value(which is an int) with anotherone...
myFuncThatBadlyNeedsInts((int)c);
This gives me an error, which tells me that this is not allowed.
But if i decide to get tricky and do this:
myFuncThatBadlyNeedsInts(*((int*)&c));
Now the program goes about and gives me always the result i want. My question is: Why is there a diffrence in the result of the two casts?
Shouldn't they both do the same, with the diffrence i have two unneccessary pointers in the process?
Help or the guidance to an alredy existing answer to my qustion is much appreciated.
EDIT (since i can't comment): The need for this indeed silly conversion is inheritated from a project which compares a specific memory location (as an int) with a DWORD wich is retrived from a FGPA and comes as an array. The DWORD gets read in the end as one hex-number.
I'll try to get permission to change this and THANK YOU ALL for the quick responses. I really didn't get the part of this program nor did I understand why it worked like this in the first place. Now I know someone got lucky
P.S.: Since im new here and this my first qustion please let me know what other specifics you might need or just edit my newby misshabits away.
When you do myFuncThatBadlyNeedsInts((int)c) the compiler first decay the array c to a pointer to the first element, i.e. &c[0], you then cast this pointer to an int and pass that to the function.
When you do *((int*)&c) you take the address of the array (of type int (*)[4]) and tell the compiler that it's a pointer to an int (which is not correct) and then dereference that (incorrect) int*.
So both calls are actually incorrect. The casting just silences the compiler.
If you want to treat the four bytes of the array as a single 32-bit word, there are ways to do it, but they all breaks the strict aliasing rule.
The simplest way is very close to what you have now, and is done with casting. Using C-casting you cast the pointer that c decays to as a pointer to int and dereference that:
myFuncThatBadlyNeedsInts(*(int*)c);
Note that this is not the same thing as either of your attempts.
The second way is to use a union:
union my_union
{
char bytes[sizeof(int)];
int integer;
};
Then copy the data to your unions bytes member, and read out the integer.
In the first case you are trying to cast an char array to an int - this is obviously meaningless in that an list of characters is quite different to an int.
In The second case you first take the address of the array - the & operator gives you a character pointer to the first element of the array.
Specifically the type of &c is unsigned char * - it is legal (although dangerous) to cast between pointer types thus the cast from unsigned char * to int * is legal.
Then you dereference the pointer and get the integer that is at this spot which is probably some nasty (meaningless) number derived from the first couple of characters in the string which are those bytes.
So you second solution doesn't convert from char[] to int[] which is presumably what you want, instead it give you an integer representation of the first bytes of the char array.
In the second case you get pointer from unsigned char than cast it to integer, so in fact you always use your uchar and 3 bytes just after (in this case whole array c). Because of sizeof int is 4 (usually, but not always), and size of uchar is only 1. So don't do this unless you like to shoot yourself in leg.
To be honest I don't really understand what you are going to achive in this example

How to use strtof endPointer?

Looking at the examples presented by various google results, I don't really understand how the EndPtr works. For an example:
char szOrbits[] = "686.97 365.24";
char* pEnd;
float f1 = strtof (szOrbits, &pEnd);
The function takes the pointer of the pointer that is declared after the char array, does that mean that the actual type and contents of the pointer are irrelevant and the pointer is guaranteed to be allocated right after the array thus making its address the end point?
I tried using it like this:
ret.push_back(EquationPiece(strtof(&Source[mark], (char**)&Source[i])));
where ret is a vector, Source is a char array, mark is where the number begins and i is the next byte after the number but I'm getting some strange results. Is my usage incorrect or should I seek for the bug elsewhere?
Although the reference page describes the parameter pendptr as a reference to a char* object this might be misundestood. In C we have only pointers and the second parameter of strtof is a pointer to a pointer to char.
You can utilize this parameter to get the point in the input char array that could not be used to convert the char array to the output float. If the pointer points to a '\0' than the array has been converted entirely. If it points to something different you can start error handling or further processing of the char array.
You should never cast any pointer when you are not sure what it means. Cast tells the compiler that the programmer knows it better. Depending on the meaning of your EquationPiece it might be useful to pass the endPtr:
ret.push_back(EquationPiece(strtof(&Source[mark], pEnd));

Passing in and modifying an array in a function

I have been looking at other posts and trying to get this working for a bit, but can't seem to manage it.
Basically I want to pass a "char myArray[10]" though into a function, have the function assign the values and then hand it back. It generally looks like this at the moment:
int MyClass::GetArray(char array[10])
{
char p[10];
... // a value is assigned to p
memcpy(&array, &p, sizeof(p)); // Here array ends up being 0x3232323232323232 <Error reading characters of string.>
return 0;
}
Called with:
char array[10];
myclass.GetArray(array);
So, I assume I need to pass the array through as a reference to the array[10] created before calling the function. But for that I am unsure how to create a pointer to a fixed array without making it either a general char* pointer or a pointer to an array of chars.
Secondly is the memcpy error (in the code comments above). I'm not sure if that is related or not though.
Then thing is that when you pass an array to a function, it decays to a pointer. So when you use the address-of operator & on array in the function, you're taking the address of the pointer, meaning you get a pointer to a pointer.
That, by the way, leads to undefined behavior.
Other than that it's all okay, you don't have to pass the array (or rather, pointer) by reference. It's just not very... C++-ish. :)

How do you declare a pointer to a function that returns a pointer to an array of int values in C / C++?

Is this correct?
int (*(*ptr)())[];
I know this is trivial, but I was looking at an old test about these kind of constructs, and this particular combination wasn't on the test and it's really driving me crazy; I just have to make sure. Is there a clear and solid understandable rule to these kind of declarations?
(ie: pointer to... array of.. pointers to... functions that.... etc etc)
Thanks!
R
The right-left rule makes it easy.
int (*(*ptr)())[];can be interpreted as
Start from the variable name ------------------------------- ptr
Nothing to right but ) so go left to find * -------------- is a pointer
Jump out of parentheses and encounter () ----------- to a function that takes no arguments(in case of C unspecified number of arguments)
Go left, find * ------------------------------------------------ and returns a pointer
Jump put of parentheses, go right and hit [] ---------- to an array of
Go left again, find int ------------------------------------- ints.
In almost all situations where you want to return a pointer to an array the simplest thing to do is to return a pointer to the first element of the array. This pointer can be used in the same contexts as an array name an provides no more or less indirection than returning a pointer of type "pointer to array", indeed it will hold the same pointer value.
If you follow this you want a pointer to a function returning a pointer to an int. You can build this up (construction of declarations is easier than parsing).
Pointer to int:
int *A;
Function returning pointer to int:
int *fn();
pointer to function returning a pointer to int:
int *(*pfn)();
If you really want to return a pointer to a function returning a pointer to an array of int you can follow the same process.
Array of int:
int A[];
Pointer to array of int:
int (*p)[];
Function returning pointer ... :
int (*fn())[];
Pointer to fn ... :
int (*(*pfn)())[];
which is what you have.
You don't. Just split it up into two typedefs: one for pointer to int array, and one for pointer to functions. Something like:
typedef int (*IntArrayPtr_t)[];
typedef IntArrayPtr_t (*GetIntArrayFuncPtr_t)(void);
This is not only more readable, it also makes it easier to declare/define the functions that you are going to assign the variable:
IntArrayPtr_t GetColumnSums(void)
{ .... }
Of course this assumes this was a real-world situation, and not an interview question or homework. I would still argue this is a better solution for those cases, but that's only me. :)
If you feel like cheating:
typedef int(*PtrToArray)[5];
PtrToArray function();
int i = function;
Compiling that on gcc yields: invalid conversion from 'int (*(*)())[5]' to 'int'. The first bit is the type you're looking for.
Of course, once you have your PtrToArray typedef, the whole exercise becomes rather more trivial, but sometimes this comes in handy if you already have the function name and you just need to stick it somewhere. And, for whatever reason, you can't rely on template trickery to hide the gory details from you.
If your compiler supports it, you can also do this:
typedef int(*PtrToArray)[5];
PtrToArray function();
template<typename T> void print(T) {
cout << __PRETTY_FUNCTION__ << endl;
}
print(function);
Which, on my computer box, produces void function(T) [with T = int (* (*)())[5]]
Being able to read the types is pretty useful, since understanding compiler errors is often dependent on your ability to figure out what all those parenthesis mean. But making them yourself is less useful, IMO.
Here's my solution...
int** (*func)();
Functor returning an array of int*'s. It isn't as complicated as your solution.
Using cdecl you get the following
cdecl> declare a as pointer to function returning pointer to array of int;
Warning: Unsupported in C -- 'Pointer to array of unspecified dimension'
(maybe you mean "pointer to object")
int (*(*a)())[]
This question from C-faq is similar but provides 3 approaches to solve the problem.