exercise problem -- not homework

Discussion in 'C++' started by Charles, Jul 28, 2003.

  1. Charles

    Charles Guest

    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
     
    Charles, Jul 28, 2003
    #1
    1. Advertising

  2. <Charles> wrote in message
    news:...

    > 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
    --
    jb

    (replace y with x if you want to reply by e-mail)
     
    Jakob Bieling, Jul 28, 2003
    #2
    1. Advertising

  3. On Mon, 28 Jul 2003 06:22:05 -0400, wrote:

    >>Here the function should set the bytes indicated by the
    >>starting address in void* to a value (which has not been
    >>passed right now, but you are going to change this). There
    >>are n bytes in sequence.

    >
    >>Hint: You can't do anything sensible with a void*, thus you
    >>will need to cast the void* to some other pointer type. So
    >>the question is: To what data type will you cast the void
    >>pointer, such that the pointer can point to individual bytes
    >>
    >>Hint2: sizeof( unsigned char) equals 1 per definition.
    >> unsigned char is also often used, if somebody deals
    >> with memory on the byte level.

    >
    >>
    >>You are asked to rewrite the standard function memset. Maybe
    >>looking up its documentation may be of some help. Other then
    >>that: The assignment seems to be pretty clearto me. Are there
    >>any specific quesitions instead of the global: 'Help!'

    >
    > 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
     
    Nils Petter Vaskinn, Jul 28, 2003
    #3
  4. <Charles> wrote in message
    news:...
    > 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
    --
    jb

    (replace y with x if you want to reply by e-mail)
     
    Jakob Bieling, Jul 28, 2003
    #4
  5. Charles

    Charles Guest


    > 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;
    }
     
    Charles, Jul 28, 2003
    #5
  6. Charles

    Charles Guest

    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
     
    Charles, Jul 28, 2003
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. tmp123
    Replies:
    36
    Views:
    811
    Dave Thompson
    Mar 3, 2006
  2. joebenjamin
    Replies:
    31
    Views:
    903
    Mark McIntyre
    Oct 11, 2007
  3. Three Headed Monkey

    not a homework question

    Three Headed Monkey, Mar 12, 2008, in forum: C Programming
    Replies:
    35
    Views:
    882
    user923005
    Mar 17, 2008
  4. Trip Technician
    Replies:
    7
    Views:
    285
  5. John Ladasky
    Replies:
    25
    Views:
    272
    John Ladasky
    Jul 25, 2013
Loading...

Share This Page