exercise problem -- not homework

C

Charles

I am going through the exercises and Bruce Eckel's Thinking in C++ and
I ran into an exercise that wasn't included in his solutions that I
think I could use some assistance with.

Exercise 3-26 pg 213:

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.

Here is what I have so far: (which isnt much)

#include <iostream>
using namespace std;

void fn (void* v, int n)
{
}


int main ()
{
int a[10];
void* vp = static_cast<void*>(&a);

return 0;
}

Maybe somebody can help me translate what is being asked in the
exercise.



Thanks in advance for any tips,
Charles
 
J

Jakob Bieling

Did I correctly recast the void to the type you are describing?

The cast itself is correct, but it is of no use for you.
How do I set the value of each byte in the range as it applies to the
int array?

See below.
#include <iostream>
using namespace std;

void fn (void* v, size_t num_bytes, int value)
{

This is what Karl meant. You cannot really work with a void-pointer,
because it is an incomplete type. So you need to cast 'v' to something that
allows you to work on bytes.
for (size_t i = 0; i < num_bytes; ++i)
// set the bytes here How?

Once you have the above casting done, you can easily assign to the byte
array, just like you would do any other variable assignment.
}

int main ()
{
int a[10], number = 10;

void* p_v = static_cast<void*>(&a);
unsigned char* p_byte = reinterpret_cast<unsigned char*>(p_v);

If you think about the use of this, what would it do? You cast to
'unsigned char', but what for?
fn (p_v, sizeof p_byte, number);

In the excerise it said your function takes a number "indicating a
number of bytes" .. you can assume that the number of bytes of the array you
are passing to the function are meant. But that is not what you are passing
there. You are passing the size of a pointer-to-unsigned-char, which is 4 on
my machine. But the size of your array that you are passing is 10 (not 10
bytes!), and each element occupies several bytes by itself. By this, you
should be able to figure out the actual size of the array in bytes.
return 0;
}

hth
 
N

Nils Petter Vaskinn

Did I correctly recast the void to the type you are describing?

How do I set the value of each byte in the range as it applies to the
int array?

Charles


#include <iostream>
using namespace std;

#define ARRAY_SIZE 10
void fn (void* v, size_t num_bytes, int value)

void fn (void* v, size_t num_bytes, char value)

Since you'll be writing the value into each individual byto of the array
value should probably be of type char.
{
for (size_t i = 0; i < num_bytes; ++i)
// set the bytes here How?

Pointer arithmetic:

for(pointer = start ;pointer < start + size; pointer++) {
*pointer = value;
}
}

int main ()
{

int a[ARRAY_SIZE];
char number = 10;
void* p_v = static_cast<void*>(&a);
unsigned char* p_byte = reinterpret_cast<unsigned char*>(p_v);

fn (p_v, sizeof p_byte, number);

fn (p_v, sizeof(int) * ARRAY_SIZE ,number)
return 0;
}


hth
npv
 
J

Jakob Bieling

Here is what I have in an attempt to apply the advice given to me in
this thread. It seems to satisfy the criteria given in the
exercise... Comments please?


#include <iostream>
using namespace std;

void fn (void* v, size_t num_bytes, int val)
{
unsigned char* p_addr =
reinterpret_cast<unsigned char*>(v);
unsigned char byte =
static_cast<unsigned char>(val);

cout << "num_bytes = " << num_bytes << endl;

for (size_t i = 0; i < num_bytes; ++i)
{
*p_addr = byte;
p_addr++;
}
}

int main ()
{
int a[10], value = 67;

void* vp = static_cast<void*>(&a);

fn (vp, sizeof a, value);

The loop for printing the result seems wrong.
// output each of 4 bytes of int array
// index each element
for (size_t i = 0; i < (sizeof a / sizeof a[0]); ++i)
{
unsigned char* p_addr =
reinterpret_cast<unsigned char*>(a);


'a ' is of type 'int'. Above, you are casting that to 'unsigned
char*'. I think this is not what you intended to do. Instead, you probably
want to take the /address/ of the i-th element in the a-array, so that
p_addr points to the first byte that the i-th 'int' in the array occupies.
(*)
unsigned char byte =
static_cast<unsigned char>(a);


I do not think this is intended either. 'byte' contains part of 'a '.
Seeing the loop below, you print out 'byte', but you never change its value,
until the point of execution reaches the above line again. You can actually
remove this line completely.
// iterate each byte
for (size_t j = 0; j < sizeof(int); ++j)
{
cout << byte ;
p_addr++;

You seem to be thinking that incrementing 'p_addr' implicitly changes
'byte' as well. But this is not the case. The value you have assigned to
'byte' is just there, without any connection to where it came from.

If you did as I explained (the paragraph marked with an asterisk), then
you only need to change 'byte' in the above loop to '*p_addr' and it will
print out the real values. This works, because before the loop starts, you
let 'p_addr' point to the first byte of the element in the array (see
above). The inner loop then prints the bytes as you intended.
}
cout << endl;
}

return 0;
}



The output on my machine is:
num_bytes = 40
CCCC
CCCC
CCCC
CCCC
CCCC
CCCC
CCCC
CCCC
CCCC
CCCC

hth
 
C

Charles

The loop for printing the result seems wrong.
You are correct.
I noticed this too after I posted.

Here is my correction.


#include <iostream>
using namespace std;

void fn (void* v, size_t num_bytes, int val)
{
unsigned char* p_addr =
reinterpret_cast<unsigned char*>(v);
unsigned char byte =
static_cast<unsigned char>(val);

cout << "num_bytes = " << num_bytes << endl;

for (size_t i = 0; i < num_bytes; ++i)
{
*p_addr = byte;
p_addr++;
}
}

int main ()
{
int a[10], value = 67;

void* vp = static_cast<void*>(&a);

fn (vp, sizeof a, value);

// output each of 4 bytes of int array
unsigned char* byte =
reinterpret_cast<unsigned char*>(vp);

// iterate number of elements
for (size_t i = 0; i < (sizeof a / sizeof a[0]); ++i)
{
// iterate each byte per element
for (size_t j = 0; j < sizeof(int); ++j)
{
cout << *byte;
byte++;
}
cout << endl;
}

return 0;
}
 
C

Charles

This seems to be correct now for displaying the byte content of each
of the array elements.

If i change line 15

from
*p_addr = byte;

to
*p_addr = byte++;

I get the following output:

num_bytes = 40
CDEF
GHIJ
KLMN
OPQR
STUV
WXYZ
[\]^
_`ab
cdef
ghij

which, I think, shows that the program is setting and displaying 40
bytes for the 10 element int array.

Charles
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top