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
Related
I'm given a method header as so:
char* thisMethod(char* input){}
is it possible to say,
char var = input[0];
? I know that "input" will be in the form of a char array.
I'm obviously new to C++ pointers are throwing me off. I tried researching how to work with char pointer function arguments but couldn't find anything specific enough to help. Thanks for the help.
There is a misconception that may lead you into further troubles:
I know that "input" will be in the form of a char array.
NOPE: By the scope of that function, input is a pointer to a character. The function has no way to know where such a pointer comes from.
If it has been taken from an array upon calling the function than it will be a pointer to the first element of that array.
Because pointer have an arithmetic that allows to add offsets and because the [] operator applied to pointers translates as a[b] = *(a+b) by definition, in whatever code, if a is a pointer, *a and a[0] are perfect synonymous.
Think to an array as a sequence of boxes and a pointer as your hand's index finger
adding an offset to a finger (like finger+2) means "re-point it aside" and de-referencing it (like *finger) means "look inside what it points to".
The [] operator on pointers is just a shortcut to do both operations at once.
Arrays are another distinct thing. Don't think to them when dealing with pointers, since -in more complex situations, like multidimensional array or multi-indirection pointers - the expression a[b][c] won't work anymore the same way.
There are two ways to get a value from a pointer, * and []. The following are equivalent:
char var1 = *input;
char var2 = input[0];
Using the brackets is more common when you know you were passed an array, since it allows you to supply an index. You need some way of knowing where the end of the array is so that you don't attempt any access past it, your function is missing that important detail.
As long as it's inside the function and input points to something valid ( not NULL/nullptr and not a garbage location ) then doing char var = input[0]; is just fine. It's the same as char var = *input.
P.S If it's supposed to be a string I recommend using std::string.
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));
int *p;
scanf("%d",&p);
printf("%d\n",p);
In my past understandings,the "p" is a address,but now it seems that the p is a simple variable.
I cant understand why these 3 lines code are right!!!
can you help me?
This will only work as long as a pointer is the same size as an integer because you are basically treating the pointer as an integer. That is, if int is a 32-bit integer, and a pointer void* is a 32-bit address.
The way it should be written:
int p; // not the lack of the *
scanf("%d",&p); // this gives scanf the address of p
printf("%d\n",p); // this uses p's value
Which will actually use p as an integer instead of declaring it as a pointer and treating it like an integer.
They are not right. They just seem to work, because you ask scanf to store an integer and the address where to store it is the address of the pointer p. You are basically treating the storage of the pointer itself as the storage of an integer. Likewise for printf, you pass the address of the pointer (which contains the integer) and ask printf to read it from there as... an integer. You could even change the first line to
float* p;
and it would still seem to work. In the end, this is a good example of why you should avoid C-style interfaces which are not type-safe.
If I will explain through your statements, then it will be
int *p; //Declaration of pointer variable p, which can hold the address of integer variable
scanf("%d",&p); //Getting input, will be stored at address of pointer variable p
printf("%d\n",p); //It will display the value stored at &p
The code above is not really correct, and it is built on top of a fair amount of assumptions and C constructs.
The first assumption is that a pointer and an int have the same size, which will break in most (all I know) 64bit platforms. It is then using a type unsafe interface (variadic function arguments) to pass the address of an int* as if it was the address of an int. The code inside the scanf will assume that it is writting to an int and write over the bits... but the type is not an int* and that bit pattern might or not make sense even in the platforms where the sizeof(int) = sizeof(int*)
That code is not right at all.
Some (bad) compilers may be unable to detect the problems because both printf and scanf are variadic functions... but for example g++ would warn you that the types passed don't match with the ones specified in the format strings.
Given a void pointer, if I want to make the void pointer point to x bytes ahead, how will this be best done? Is there a better way than casting to a char pointer?
Is there a better way than casting to
a char pointer?
No (except having a char * instead of a void * to begin with, so you don't have to cast it at all).
If this is not desirable or possible, then the only way is:
ptr = static_cast<char *>(ptr) + offset;
(Note: if you are doing this sort of stuff in C++, usually there is a much better solution. Unless you are an expert and you already ruled out every other alternative, I suggest you post a new question asking if there is a better way to do what you're trying to do!)
Take a look at this question, and this question. To summarise, the answer is to cast to char * for arithmetic at a byte level.
Given a void pointer, if I want to make the void pointer point to x bytes ahead, how will this be best done? Is there a better way than casting to a char pointer?
If you have a void*, you don't know that "x bytes ahead" is a valid address. You don't know that creating such a pointer won't crash your program.
And that is why it can't be done with void*.
You can only perform pointer arithmetics on pointers into an array. And if you have a pointer into an array, you know the type of the array, and can use the equivalent pointer type.
If you want some kind of abstract "byte pointer" (say, if you're implementing a memory pool and need to point to a specific offset into a buffer), you should use char* or unsigned char*, not void*.
When doing pointer arithmetic compiler wants to take into account what it knows about the type that the pointer points to.
For example if you have a int *myint. Then these two statements actually do the same thing:
int a = *(myint+5);
and
int a = myint[5];
in this case myint+5 does not mean "the address of myint plus 5" but "the address of myint plus 5*sizeof(int))"
So in case of a void * the compiler can't make any assumptions what void * + 5 should mean. So before you use a void * it kind of forces you to specify how you want to use it.
you can convert the pointer to normal integer , do the increment or whatever operation , then you can assign the integer to that pointer , hope it helps
Here was my problem
void *inputAudioBuffer;
c++ was not letting me do this
UInt16 *inputBuffer = (UInt16 *)(inputAudioBuffer + inputBufferOffset);
after doing a type cast I was able to do it
UInt16 *inputBuffer = (UInt16 *)( (UInt16 *) inputAudioBuffer + inputBufferOffset);
In difference to the other people answering this question, it seems to me as if a simple +x (no casting at all) is sufficient to access the address x bytes ahead of your void pointer. The compiler might not like it, but at least in the cases I have used this, it has worked. I'm using g++ (gcc)...
So as long as you know what you're doing, no probs.
#include<iostream>
using namespace std;
int main()
{
int *p,*c;
p=(int*)10;
c=(int*)20;
cout<<(int)p<<(int)c;
}
Somebody asked me "What is wrong with the above code?" and I couldn't figure it out. Someone please help me.
The fact that int and pointer data types are not required to have the same number of bits, according to the C++ standard, is one thing - that means you could lose precision.
In addition, casting an int to an int pointer then back again is silly. Why not just leave it as an int?
I actually did try to compile this under gcc and it worked fine but that's probably more by accident than good design.
Some wanted a quote from the C++ standard (I'd have put this in the comments of that answer if the format of comments wasn't so restricted), here are two from the 1999 one:
5.2.10/3
The mapping performed by reinterpret_cast is implementation defined.
5.2.10/5
A value of integral type or enumeration type can be explicitly converted to a pointer.
A pointer converted to an integer of sufficient size (if ant such exists on the implementation)
and back to the same pointer type will have its original value; mappings between pointers and
integers are otherwise implementation-defined.
And I see nothing mandating that such implementation-defined mapping must give a valid representation for all input. Otherwise said, an implementation on an architecture with address registers can very well trap when executing
p = (int*)10;
if the mapping does not give a representation valid at that time (yes, what is a valid representation for a pointer may depend of time. For instance delete may make invalid the representation of the deleted pointer).
Assuming I'm right about what this is supposed to be, it should look like this:
int main()
{
int *p, *c;
// Something that creates whatever p and c point to goes here, a trivial example would be.
int pValue, cValue;
p = &pValue;
c = &cValue;
// The & operator retrieves the memory address of pValue and cValue.
*p = 10;
*c = 20;
cout << *p << *c;
}
In order to assign or retrieve a value to a variable referenced by a pointer, you need to dereference it.
What your code is doing is casting 10 into pointer to int (which is the memory address where the actual int resides).
addresses p and c may be larger than int.
The problem on some platforms you need
p = (int*) (long) 10;
See GLIB documentation on type conversion macros.
And for the people who might not find a use for this type of expressions, it is possible to return data inside pointer value returning functions. You can find real-world examples, where this case it is better to use this idiom, instead of allocating a new integer on the heap, and return it back - poor performance, memory fragmentation, just ugly.
You're assigning values (10 and 20) to the pointers which obviously is a potential problem if you try to read the data at those addresses. Casting the pointer to an integer is also really ugly. And your main function does not have a return statement. That is just a few things.
there is more or less everything wrong with it:
int *p,*c;
p=(int*)10;
c=(int*)20;
afterwards p is pointing to memory address 10
afterwards c is pointing to memory address 20
This doesn't look very intentional.
And I suppose that the whole program will simply crash.