Question about this exercise, convert to void*

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.


And here is my working code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
using namespace std;

void byteChanger(void* intArray, int numBytes, int valueReset) {
  //must convert void* back to int* 
  int* p2array = static_cast<int*>(intArray);  
  for(int* i = p2array; i < p2array + numBytes; i++) {
    *i = valueReset;
  }
}

void printArray(int* array) {
  for(int i = 0; i < 10; i++){
    if(i == 9){
      cout<<array[i]<<endl;
    }else{
      cout<<array[i]<<", ";
    }
  }
}


int main() {
  int intArray[10] = {1,43,65,235,7,4454,34,86,23,43};
  void* pIntArray = static_cast<void*>(intArray);
  
  printArray(intArray);  
  byteChanger(pIntArray, 5, 99);  
  printArray(intArray);
  
  system("pause");
}


Now, Im wondering if there is a way I missed that you can do this without having to convert the int array from void* back to int* within the function?
I know when you pass an array it passes the address of the first element anyway, so passing an array is essentially the same as passing a pointer.
But when it comes to the pointer arithmetic I cant add an int to a void* which is why I have to cast the void* back to int* within the function..

Did I misread the question? or are these questions more designed to get you just doing things that arent really.. practical? Im kind of getting tired of this book if this is the case... I just dont see the need to convert to the void, seems unnecessary..

thanks for any input
Last edited on
Your function does not satisfy the assignment. According to the assignment

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


You have to set bytes at the adrress not elements of the array.
And such function already exists. It is named memset and declared in header <cstring>
I assumed the second variable
a number (indicating number of bytes)
to be the "range" that the question later mentions:
The function should set each byte in the specified range to the specified value


I do set the bytes at the address, in the function *i is the address which I set to the third argument... but I see now that.. with an array of int, each element is 4 bytes.. so if I changed 5 the first five bytes from the starting address things would be quite different..

I guess I just dont know how to do the pointer maths right to increment by 1 byte at a time.. and as far as I know, I cannot increment a void pointer type, so casting back to an int or.. something else is the only option here?
Im actually lost :/
Last edited on
Convert it to unsigned char *

unsigned char *p2array = reinterpret_cast<unsigned char *>(intArray);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
using namespace std;

void byteChanger(void* inputAddr, int numBytes, int valueReset) {
    unsigned char* startAddr = (unsigned char*)inputAddr;
    for(int i = 0; i < numBytes; i++) {
    *startAddr = valueReset;
    startAddr++;
    
  }
}

void printArray(int* array) {
  for(int i = 0; i < 10; i++){
    if(i == 9){
      cout<<array[i]<<endl;
    }else{
      cout<<array[i]<<", ";
    }
  }
}


int main() {
  int intArray[10] = {1,2,3,4,5,6,7,8,9,10};
  void* pIntArray = static_cast<void*>(intArray);
  
  printArray(intArray);  
  byteChanger(pIntArray, 10, 3);  
  printArray(intArray);
  
  system("pause");
}


I believe this now satisfies the question.. I guess the cast to void is just an intermediary? I cannot think of any other way other than casting the void* pointer to a char pointer and then incrementing it to be able to change an indivdual byte at a time..

If you know of another way, please let me know. Id like to know how the roots of the code work rather than just jumping in and resorting to using things like memset etc, even though they supposedly do the same thing

edit::

dang these forums are wonky sometimes, I didnt see your reply until just now Vlad. Glad to know I figured out the right way though :) appreciate the help

Is there any specific reason for unsigned char? my outputs dont change whether signed or unsigned
Last edited on
next question: I think I nailed this one,
Create a function that takes a pointer to an array of double and a value indicating the size of that array. The function should print each element in the array. Now create an array of double and initialize each element to zero, then use your function to print the array. Next use reinterpret_cast to cast the starting address of your array to an unsigned char*, and set each byte of the array to 1 (hint: you’ll need to use sizeof to calculate the number of bytes in a double). Now use your array-printing function to print the results. Why do you think each element was not set to the value 1.0?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
using namespace std;

void initialize(double inputArray[], int initialValue, int arraySize);
void printArray(double* inputArray, int arraySize);
void printBytes(double* inputArray, int arraySize);
void setByte(double* inputArray, int newByteValue, int arraySize);

int main() {
  int size = 10;
  double dArray[size];
  
  initialize(dArray, 0, size);
  cout<<"Array Initialized:\n"<<endl;
  printArray(dArray, size);
  cout<<"Each individual byte:"<<endl;
  printBytes(dArray, size);
  setByte(dArray, 254, size);
  cout<<"Array contents after individual byte setting:\n"<<endl;
  printArray(dArray, size);
  cout<<"Each individual byte:"<<endl;
  printBytes(dArray, size);

  system("pause");
}

void initialize(double inputArray[], int initialValue, int arraySize){
  for(int i = 0; i < arraySize; i ++) {
    inputArray[i] = (double)initialValue;
  }
}
  

void printArray(double* inputArray, int arraySize) {
  for(int i = 0; i < arraySize; i++) {
    if(i == arraySize-1) {
      cout<<i+1<<": "<<inputArray[i]<<endl;
      cout<<"-------------------"<<endl;
    }else {
      cout<<i+1<<": "<<inputArray[i]<<endl;
    }
  }
}

void printBytes(double* inputArray, int arraySize) {
  unsigned char* startAddr = (unsigned char*)inputArray;
  for(int i = 0; i < (sizeof(double) * arraySize); i++) {
    if(i % 8 == 0) {
      cout<<"\nBytes of element #"<<i/8+1<<endl;
      cout<<"-------------------"<<endl;
    }
    if(i == (sizeof(double) * arraySize)-1) {
      cout<<"0x"<<hex<<(long)startAddr<<" :: "<<dec<<(long)*startAddr<<endl;
      cout<<"-------------------\n"<<endl;
    } else {  
      cout<<"0x"<<hex<<(long)startAddr<<" :: "<<dec<<(long)*startAddr<<endl;
      startAddr++;
    }
  }
}

void setByte(double* inputArray, int newByteValue, int arraySize) {
  unsigned char* startAddr = (unsigned char*)inputArray;
  for(int i = 0; i < (sizeof(double) * arraySize); i++) {
    *startAddr = newByteValue;
    startAddr++;
  }
}


So I went a bit above and beyond, creating an initialization function, as well as separate print functions, one to output the array elements and one which outputs each individual byte and their values, and one to set the byte values..

The question says to use reinterpret_cast, but just like in the previous exercise saying to use static_cast, they are both unnecessary and a regular old (unsigned char*)var cast works fine..
anyone?
Topic archived. No new replies allowed.