|
#1
|
|
|
|
|
Hi,
I am trying the following exercise in a book: //Define an array of int. //Take the starting address of that array and use static_cast to convert it into an void*. //Write a function that takes a void*, a number (indicating a number of bytes), //and a value (indicating the value to which each byte should be set) as arguments. //The function should set each byte in the specified range to the specified value. //Try out the function on your array of int. #include <iostream> void func(void* p,short int s,unsigned char v) { unsigned char * pp=reinterpret_cast<unsigned char*>(p); for (int i=0;i<s;i++) { *(pp+i)=v; } } int main() { unsigned int iA[10]; for (int i=0;i<10;i++) { int j; std::cout << "gimme some int" << std::endl; std::cin >> j; iA[i]=j; } for (int i=0;i<10;i++) { std::cout << iA[i] << std::endl; } void * p=static_cast<void *>(&iA); std::cout << "gimme a number of bytes to change" << std::endl; short i; std::cin >> i; std::cout << "gimme a value I will force those bytes to" << std::endl; char j; std::cin >> j; func(p,i,j); for (int i=0;i<10;i++) { std::cout << iA[i] << std::endl; } } I am then expecting that, if I set my whoke array to zero, and I suggest to change just one byte to 255, I'll have iA[0]=255 and all the other worth 0 (my int are 4 bytes long so when I change 1 byte I just change part of the first int and shouldn't touch the rest). But I get 50 for the first element instead. Can you please tell me where I am wrong? Thank you |
|
|
|
#2
|
|
|
|
|
Fil wrote:
[..] > } > > I am then expecting that, if I set my whoke array to zero, and I suggest to > change just one byte to 255, I'll have iA[0]=255 and all the other worth 0 > (my int are 4 bytes long so when I change 1 byte I just change part of the > first int and shouldn't touch the rest). > But I get 50 for the first element instead. > > Can you please tell me where I am wrong? > Thank you Fil: What kind of book is this? Doesn't sound very good to me. Anyway, lotsa things wrong here: 1. Pointer to first element of array is iA, or &iA[0] 2. Don't need to cast to void* void* p = iA; 3. Can't input 255 to a char value: unsigned int j; std::cin >> j; 4. You need to cast back to the original type. Also, casting a void* to a pointer type should be done with static_cast, not reinterpret cast unsigned int* pp = static_cast<unsigned int*>(p); Try it now ... |
|
#3
|
|
|
|
|
Fil <Fil> wrote:
> void func(void* p,short int s,unsigned char v) > { > unsigned char * pp=reinterpret_cast<unsigned char*>(p); > for (int i=0;i<s;i++) > { > *(pp+i)=v; > } > } > std::cout << "gimme a value I will force those bytes to" << std::endl; > char j; > std::cin >> j; > func(p,i,j); > > I am then expecting that, if I set my whoke array to zero, and I > suggest to change just one byte to 255, I'll have iA[0]=255 and all > the other worth 0 (my int are 4 bytes long so when I change 1 byte I > just change part of the first int and shouldn't touch the rest). > But I get 50 for the first element instead. When you do cin >> j, and j is a char variable, you just read one character from the stream. The input is "255", and j gets the first character of that. It so happens that the ASCII code for '2' is 50, which is what you pass to func(). |
|
#4
|
|
|
|
|
"Igor Tandetnik" wrote:
> When you do cin >> j, and j is a char variable, you just read one > character from the stream. The input is "255", and j gets the first > character of that. It so happens that the ASCII code for '2' is 50, > which is what you pass to func(). damn that's true. I tried with int and it's working as expected. Thanks a lot. [..] |
|
#5
|
|
|
|
|
"David Wilkinson" wrote:
> What kind of book is this? Doesn't sound very good to me. The book is told to be very good but the code you see is my solution to the exercise, not the book itself. Thks for the compliment ;) > Anyway, lotsa things wrong here: > > 1. Pointer to first element of array is iA, or &iA[0] Yep, true I wrote &iA. Do you know why it's working ayway? > 2. Don't need to cast to void* > > void* p = iA; My book is suggesting to explicitly cast all changes of types (because apparently casting is a major source of bugs and to have them explicitly stated helps debugging) > 3. Can't input 255 to a char value: > > unsigned int j; > std::cin >> j; I was looking for a 1 byte numerical variable and was hoping that my char would have been interpreted as a number. 1 unsigned byte goes from 0 to 2^8-1 = 255. Isn't it true? > 4. You need to cast back to the original type. Also, casting a void* to a > pointer type should be done with static_cast, not reinterpret cast > > unsigned int* pp = static_cast<unsigned int*>(p); I thought that when I was assigning new types to pointers (that have possibly different length), the meaning of the data it points to is completely different and subject to re-interpretation. When do you suggest using reinterpret_cast? Thank you for the help |
|
#6
|
|
|
|
|
Fil wrote:
[..] > > I was looking for a 1 byte numerical variable and was hoping that my char > would have been interpreted as a number. > 1 unsigned byte goes from 0 to 2^8-1 = 255. Isn't it true? >> I thought that when I was assigning new types to pointers (that have > possibly different length), the meaning of the data it points to is > completely different and subject to re-interpretation. When do you suggest > using reinterpret_cast? Fil: 1. Yes, I guess &iA works. 2. Any pointer can be converted to void* without a cast. The cast is not wrong, just not needed. 3. Igor explained why you cannot input to char (or unsigned char) this way. But why did you use char, not unsigned char. 255 is not valid value for char. 4. reinterpret_cast is for converting types that are unrelated, like int and int*. reinterpret cats are normally not portable, and should be avoided if possible. |
|
#7
|
|
|
|
|
> Fil:
> > 1. Yes, I guess &iA works. > > 2. Any pointer can be converted to void* without a cast. The cast is not wrong, > just not needed. > > 3. Igor explained why you cannot input to char (or unsigned char) this way. But > why did you use char, not unsigned char. 255 is not valid value for char. Oh I thought I used it unsigned as in my function parameters (I probably forgot to harmonize my main body.) Anyway char is wrong here. Thanks again. > 4. reinterpret_cast is for converting types that are unrelated, like int and > int*. reinterpret cats are normally not portable, and should be avoided if possible. Ok I understand. So from a double* to an unsigned char* we should still use static_cast ? "Thinking in C++" uses reinterpret_cast in that case. [..] |
|
#8
|
|
|
|
|
Hi,
I was now trying to make a pointer to an array of 10 double, initialize it and play a little bit tobecome confident. That's what I wrote initially -------------------------------------------------------------------------------------- int main() { double iA[10]; double(*p)[10]; p=iA; std::cout << sizeof(iA) << std::endl; std::cout << (long)p << std::endl; p++; std::cout << (long)p << std::endl; -------------------------------------------------------------------------------------- p is my pointer to a array of 10 double. iA is my array of 10 double. So I decide to have p pointing to iA. Since I learnt that iA is the address of the first element of the array this is the address I want p to contain. So I write p=iA. But it doesn't work. I thought I was doing something as natural as: int a; int * p; p=&a; Instead it works if I write p=&iA which makes no sense to me because iA is an address and I never asked to have it stored anywhere (I mean that an address of a pointer makes sense if the pointer has been created. Here I just have an expression that means, as far as I've learnt, the address of(something representing already an address)). What also works is : p=reinterpret_cast<double(*)[10]>(iA); Is this the right way to do? static_cast doesn't work here: the compiler says: cannot convert from 'double [10]' to 'double (*)[10]' If I write ... p=static_cast<double(*)[10]>(&iA[0]); .... I got : cannot convert from 'double *' to 'double (*)[10]' This difference let me think that iA is more than &iA[0]. I maybe need to read something more thourough on this. Can you please shed some light on the true nature of Arrays Well I am happy to see that sizeOf(iA) is indeed sizeOf(double)*10. That gives me a little bit of confidence. |
|
#9
|
|
|
|
|
Fil wrote:
>> 4. reinterpret_cast is for converting types that are unrelated, like int and >> int*. reinterpret cats are normally not portable, and should be avoided if possible. > > Ok I understand. > So from a double* to an unsigned char* we should still use static_cast ? > "Thinking in C++" uses reinterpret_cast in that case. No, to convert between pointer types other than void* requires reinterpret_cast. Converting between such types is always "wrong", whereas casting from void* to int* could be "right" if the object is really pointing to an int. In a well-designed C++ program there should not be any need for casts. |
|
#10
|
|
|
|
|
Fil <Fil> wrote:
> So I write p=iA. > But it doesn't work. > > I thought I was doing something as natural as: > int a; > int * p; > p=&a; > > Instead it works if I write p=&iA which makes no sense Why? In the example above, you had to write p=&a, not p=a, and apparently didn't find it the least bit surprising. So why do you have a problem with p=&iA ? > iA is an address and I never asked to have it stored anywhere I don't understand this at all. iA is an array. There's storage allocated for this array. This storage begins at some address. &iA takes this address. > (I mean > that an address of a pointer makes sense if the pointer has been > created. First, iA is not a pointer, it's an array. Second, what you mean by "created" here? > What also works is : > p=reinterpret_cast<double(*)[10]>(iA); > Is this the right way to do? No, p=&iA is the right way to go (though declaring a pointer to an array, as in double (*p)[10], is an unusual thing to want to do in the first place). > static_cast doesn't work here: the compiler says: > cannot convert from 'double [10]' to 'double (*)[10]' > If I write ... > p=static_cast<double(*)[10]>(&iA[0]); > ... I got : cannot convert from 'double *' to 'double (*)[10]' That's pretty self-explanatory, isn't it? > This difference let me think that iA is more than &iA[0]. It is. Write a program that prints sizeof(iA) and sizeof(&iA[0]). > I maybe need to read something more thourough on this. > Can you please shed some light on the true nature of Arrays [url down] |
|
#11
|
|
|
|
|
"Igor Tandetnik" wrote:
> Fil <Fil> wrote: > > Why? In the example above, you had to write p=&a, not p=a, and > apparently didn't find it the least bit surprising. So why do you have a > problem with p=&iA ? > Because iA should already contain the address of the first element of the Array (like a fixed pointer). Ex: ------------------------------------------------------------------ #include <iostream> int main() { int a[5]; std::cout << a << " " << &a[0] << std::endl; } ------------------------------------------------------------------ So if I am writing &iA it sounds to me like address of address of ... This was confusing to me. While I am talking I also tried to display for the first time &a and it actually gives the same address than the 2 others. Waou. [..] |
|
#12
|
|
|
|
|
Fil <Fil> wrote:
> "Igor Tandetnik" wrote: >> Because iA should already contain the address of the first element of > the Array (like a fixed pointer). iA doesn't "contain" the address of the first element (whatever that may mean). iA implicitly converts to a pointer to its first element in many, but not all, situations. This is known as array-to-pointer decay. The article I referred you to (which you apparently didn't bother reading) explains this. > While I am talking I also tried to display for the first time &a and > it actually gives the same address than the 2 others. Waou. The first byte of the array is also the first byte of its first element. I'm not sure why this is surprising. |
|
#13
|
|
|
|
|
Fil wrote:
> Because iA should already contain the address of the first element of the > Array (like a fixed pointer). > Ex: > ------------------------------------------------------------------ > #include <iostream> > int main() > { > int a[5]; > std::cout << a << " " << &a[0] << std::endl; > } > ------------------------------------------------------------------ > So if I am writing &iA it sounds to me like address of address of ... > This was confusing to me. Fil: Sorry, it was me who set you of in the wrong direction here. Although I have come to understand the difference between arrays and pointers, if I want a pointer to the first element of an array iA, it seems more natural (to me) to set it equal to iA or &iA[0] rather than &iA, because the first two would be correct if iA were already a pointer, and the last would not. |
|
#14
|
|
|
|
|
"Igor Tandetnik" wrote:
> Fil <Fil> wrote: > > iA doesn't "contain" the address of the first element (whatever that may > mean). iA implicitly converts to a pointer to its first element in many, > but not all, situations. This is known as array-to-pointer decay. Ok, thanks. >The > article I referred you to (which you apparently didn't bother reading) That's offensive. I read it quickly but it says to refer to another thread so the length of the 2 combined is discouraging (especially to me who have spent now many days reading my book and making lots of exercises). Thank you for the article. [..] |
|
#15
|
|
|
|
|
"David Wilkinson" wrote:
> Fil wrote: > > Fil: > > Sorry, it was me who set you of in the wrong direction here. > > Although I have come to understand the difference between arrays and pointers, > if I want a pointer to the first element of an array iA, it seems more natural > (to me) to set it equal to iA or &iA[0] rather than &iA, because the first two > would be correct if iA were already a pointer, and the last would not. Thanks for the compassion, David. [..] |
|
|
|
|
| Similar Threads | |
| Thread | Thread Starter |
| reinterpret_cast I am trying to understand reinterpret_cast,here is what i tried, #include<iostream> #include<cstdio> using namespace std; int main() { int x=1; int* y=&x; |
saurabh |
| reinterpret_cast Hi, I've recently changed the way I call class members from callbacks, and although I've been very happy with the outcome, an issue raized it's head today. Say I have... |
Vince Morgan |
| Exercise & Sell - why not just Exercise vested stock options? [Money Deluxe 2004] Of a grant for 100 shares that have now vested fully, I choose to sell a certain portion of it, say 50 shares, and hold on to the remaining 50. To... |
H Gohel |
| Using reinterpret_cast I am using a C library in my C++ program. I open a file for reading in binary populating a char buffer. I pass this buffer to the C funtion. When it is done I write the... |
NA |
| reinterpret_cast<> Hi, wrote this piece of code on SunOS 5.9 , compiler g++ 2.95.3 trying to see the byte order of an int or short int by converting to char* . doesn't work . the char* cpt... |
Aman |
|
Privacy Policy | All times are GMT. The time now is 06:48 PM.
|
|
|