newbie question

Discussion in 'C++' started by BrianJones, Jul 11, 2004.

  1. BrianJones

    BrianJones Guest

    Having programmed in java for many years, I decided to try C++ for speed...
    Anyway, am writing this simple encryption program, and a method I have takes
    an array of chars (i.e. bytes) and swaps the two halves around e.g:

    0,1,2,3,4,5,6,7,8 -> 5,6,7,8,4,0,1,2,3

    But - it doesn't work properly and I can't see the problem? Any suggestions?
    The following is the method:

    char* swap(char* bytes)
    { long pivot;
    char *swappedBytes;
    bool parity = false; // whether length odd or even
    swappedBytes = new char[strlen(bytes)-1];
    if(strlen(bytes)%2==0)
    {
    pivot = strlen(bytes)/2;
    parity = false; // even
    }
    else
    strlen(bytes)%2==1){
    pivot = ((strlen(bytes)-1)/2);
    parity = true; // odd
    }
    if(parity)//odd
    {
    for(int i = 0;i<pivot;i++){
    swappedBytes = bytes[i+pivot+1];
    }
    for(int i = pivot+1;i<strlen(bytes);i++){
    swappedBytes = bytes[i-pivot-1];
    }
    swappedBytes[pivot] = bytes[pivot];
    }
    else if(!parity)//even
    {
    for(int i=0;i<pivot;i++){
    swappedBytes = bytes[i+pivot];
    }
    for(int i = pivot;i<strlen(bytes);i++){
    swappedBytes = bytes[i-pivot];
    }
    }
    return swappedBytes;
    }

    Thanks,
    Ben
     
    BrianJones, Jul 11, 2004
    #1
    1. Advertising

  2. On Sun, 11 Jul 2004 15:14:59 +0100, BrianJones
    <> wrote:

    > Having programmed in java for many years, I decided to try C++ for
    > speed...
    > Anyway, am writing this simple encryption program, and a method I have
    > takes
    > an array of chars (i.e. bytes) and swaps the two halves around e.g:
    >
    > 0,1,2,3,4,5,6,7,8 -> 5,6,7,8,4,0,1,2,3
    >
    > But - it doesn't work properly and I can't see the problem? Any
    > suggestions?
    > The following is the method:
    >
    > char* swap(char* bytes)
    > { long pivot;
    > char *swappedBytes;
    > bool parity = false; // whether length odd or even
    > swappedBytes = new char[strlen(bytes)-1];
    > if(strlen(bytes)%2==0)
    > {
    > pivot = strlen(bytes)/2;
    > parity = false; // even
    > }
    > else
    > strlen(bytes)%2==1){
    > pivot = ((strlen(bytes)-1)/2);
    > parity = true; // odd
    > }
    > if(parity)//odd
    > {
    > for(int i = 0;i<pivot;i++){
    > swappedBytes = bytes[i+pivot+1];
    > }
    > for(int i = pivot+1;i<strlen(bytes);i++){
    > swappedBytes = bytes[i-pivot-1];
    > }
    > swappedBytes[pivot] = bytes[pivot];
    > }
    > else if(!parity)//even
    > {
    > for(int i=0;i<pivot;i++){
    > swappedBytes = bytes[i+pivot];
    > }
    > for(int i = pivot;i<strlen(bytes);i++){
    > swappedBytes = bytes[i-pivot];
    > }
    > }
    > return swappedBytes;
    > }
    >
    > Thanks,
    > Ben
    >


    One problem is that you are accessing one past the end of your allocated
    array

    swappedBytes = new char[strlen(bytes)-1];

    for(int i = pivot+1;i<strlen(bytes);i++){
    swappedBytes = bytes[i-pivot-1];

    john
     
    John Harrison, Jul 11, 2004
    #2
    1. Advertising

  3. BrianJones

    BrianJones Guest

    "John Harrison" <> wrote in message
    news:eek:psay9ewcv212331@andronicus...
    > On Sun, 11 Jul 2004 15:14:59 +0100, BrianJones
    > <> wrote:
    >
    > > Having programmed in java for many years, I decided to try C++ for
    > > speed...
    > > Anyway, am writing this simple encryption program, and a method I have
    > > takes
    > > an array of chars (i.e. bytes) and swaps the two halves around e.g:
    > >
    > > 0,1,2,3,4,5,6,7,8 -> 5,6,7,8,4,0,1,2,3
    > >
    > > But - it doesn't work properly and I can't see the problem? Any
    > > suggestions?
    > > The following is the method:
    > >
    > > char* swap(char* bytes)
    > > { long pivot;
    > > char *swappedBytes;
    > > bool parity = false; // whether length odd or even
    > > swappedBytes = new char[strlen(bytes)-1];
    > > if(strlen(bytes)%2==0)
    > > {
    > > pivot = strlen(bytes)/2;
    > > parity = false; // even
    > > }
    > > else
    > > strlen(bytes)%2==1){
    > > pivot = ((strlen(bytes)-1)/2);
    > > parity = true; // odd
    > > }
    > > if(parity)//odd
    > > {
    > > for(int i = 0;i<pivot;i++){
    > > swappedBytes = bytes[i+pivot+1];
    > > }
    > > for(int i = pivot+1;i<strlen(bytes);i++){
    > > swappedBytes = bytes[i-pivot-1];
    > > }
    > > swappedBytes[pivot] = bytes[pivot];
    > > }
    > > else if(!parity)//even
    > > {
    > > for(int i=0;i<pivot;i++){
    > > swappedBytes = bytes[i+pivot];
    > > }
    > > for(int i = pivot;i<strlen(bytes);i++){
    > > swappedBytes = bytes[i-pivot];
    > > }
    > > }
    > > return swappedBytes;
    > > }
    > >
    > > Thanks,
    > > Ben
    > >

    >
    > One problem is that you are accessing one past the end of your allocated
    > array
    >
    > swappedBytes = new char[strlen(bytes)-1];
    >
    > for(int i = pivot+1;i<strlen(bytes);i++){
    > swappedBytes = bytes[i-pivot-1];
    >
    > john


    Surely such is not the case, since the i iterator (according to the for
    loop) is only allowed to go up to <strlen(bytes) i.e. strlen(bytes)-1 which
    is the amount of space allocated for array swappedBytes, so there shouldn;t
    be any problems?

    Ben
     
    BrianJones, Jul 11, 2004
    #3
  4. On Sun, 11 Jul 2004 15:54:37 +0100, BrianJones
    <> wrote:

    >>
    >> One problem is that you are accessing one past the end of your allocated
    >> array
    >>
    >> swappedBytes = new char[strlen(bytes)-1];
    >>
    >> for(int i = pivot+1;i<strlen(bytes);i++){
    >> swappedBytes = bytes[i-pivot-1];
    >>
    >> john

    >
    > Surely such is not the case, since the i iterator (according to the for
    > loop) is only allowed to go up to <strlen(bytes) i.e. strlen(bytes)-1
    > which
    > is the amount of space allocated for array swappedBytes, so there
    > shouldn;t
    > be any problems?
    >


    If i == strlen(bytes) - 1 and the array is size strlen(bytes) - 1, then
    you have accessed one past the end of the array.

    For instance

    int a[10];
    a[10] = 0; //error!!!

    It's exactly the same in Java.

    john
     
    John Harrison, Jul 11, 2004
    #4
  5. "BrianJones" <> wrote in message
    news:ccri2l$2nt$...
    > Having programmed in java for many years, I decided to try C++ for

    speed...
    > Anyway, am writing this simple encryption program, and a method I have

    takes
    > an array of chars (i.e. bytes) and swaps the two halves around e.g:
    >
    > 0,1,2,3,4,5,6,7,8 -> 5,6,7,8,4,0,1,2,3


    do you rather mean:

    0,1,2,3,4,5,6,7,8 -> 5,6,7,8,0,1,2,3,4

    why is 4 in the middle?
     
    Juha Kettunen, Jul 11, 2004
    #5
  6. "Juha Kettunen" <> wrote in message
    news:3WcIc.516$...
    >
    > "BrianJones" <> wrote in message
    > news:ccri2l$2nt$...
    > > Having programmed in java for many years, I decided to try C++ for

    > speed...
    > > Anyway, am writing this simple encryption program, and a method I have

    > takes
    > > an array of chars (i.e. bytes) and swaps the two halves around e.g:
    > >
    > > 0,1,2,3,4,5,6,7,8 -> 5,6,7,8,4,0,1,2,3

    >
    > do you rather mean:
    >
    > 0,1,2,3,4,5,6,7,8 -> 5,6,7,8,0,1,2,3,4
    >
    > why is 4 in the middle?



    oh, sorry, i just understood,,, only four numbers are swapped ..
     
    Juha Kettunen, Jul 11, 2004
    #6
  7. "BrianJones" <> wrote in message
    news:ccri2l$2nt$...
    > Having programmed in java for many years, I decided to try C++ for

    speed...
    > Anyway, am writing this simple encryption program, and a method I have

    takes
    > an array of chars (i.e. bytes) and swaps the two halves around e.g:
    >
    > 0,1,2,3,4,5,6,7,8 -> 5,6,7,8,4,0,1,2,3
    >
    > But - it doesn't work properly and I can't see the problem?

    [others have answered this already]
    > Any suggestions?


    First of all, if your focus is on performance, you should understand
    the performance of standard library functions and avoid unnecessary
    pessimizations. For example, calling strlen() multiple times in your
    code will imply a performance penalty. Also, it might be best to
    avoid memory allocations: the data can be swapped in-place.
    A 'performance-oriented' version of the function may look like:

    #include <algorithm>
    #include <cstring>
    using namespace std;

    // modifies the contentes of 0-terminated 'buf' as described above
    void swapHalves(char* buf)
    {
    size_t const len = strlen(buf);
    swap_ranges( buf, buf+len/2, buf+(len+1)/2 );
    }


    But as a newbie, I would start by taking advantage of standard
    C++ classes such as std::string :

    #include <string>
    using namespace std;

    // modifies the contentes of 0-terminated 'buf' as described above
    string swapHalves(const string& src)
    {
    size_t const len = src.size();
    string ans;
    ans.reserve(len); // optional, may avoid memory reallocations

    ans.append( src.end()-len/2, src.end() ); // start with 2nd half
    if( 0!=len%2 )
    ans.push_back( src[len/2] ); // appends a single character
    ans.append( src.begin(), src.begin()+len/2 ); // append 1st half
    return ans;
    }


    hth,
    Ivan
    --
    http://ivan.vecerina.com/contact/?subject=NG_POST <- e-mail contact form
    Brainbench MVP for C++ <> http://www.brainbench.com
     
    Ivan Vecerina, Jul 11, 2004
    #7
  8. "BrianJones" <> wrote in message
    news:ccri2l$2nt$...
    > Having programmed in java for many years, I decided to try C++ for

    speed...
    > Anyway, am writing this simple encryption program, and a method I have

    takes
    > an array of chars (i.e. bytes) and swaps the two halves around e.g:

    ....
    > But - it doesn't work properly and I can't see the problem? Any

    suggestions?
    > The following is the method:


    One additional point/clarification that others have not explained:
    your probram uses C-style strings, which are assumed to
    be terminated with a byte whose value is zero.
    This zero-end mark is required by string-related C library functions,
    such as strlen. strlen has to scan the string to find the first zero-value,
    from which it computes the length of the string.
    This means that:
    - a byte value of 0 ( not '0' ) in your source string will be
    interpreted as an end-of-string signal.
    - in your output, you'll probably also want to copy
    the zero-termination marker -- and to allocate it as well.
    - calling strlen can be slow (it takes linear time, not constant time).

    All these problems disappear if you use the C++ std::string class instead
    of character arrays -- as in the second example I previously posted.

    hth,
    Ivan
    --
    http://ivan.vecerina.com/contact/?subject=NG_POST <- e-mail contact form
     
    Ivan Vecerina, Jul 11, 2004
    #8
  9. "BrianJones" <> wrote:

    > Having programmed in java for many years, I decided to try C++ for speed...
    > Anyway, am writing this simple encryption program, and a method I have takes
    > an array of chars (i.e. bytes) and swaps the two halves around e.g:
    > 0,1,2,3,4,5,6,7,8 -> 5,6,7,8,4,0,1,2,3


    I take it you meant:

    > 0,1,2,3,4,5,6,7 -> 4,5,6,7,0,1,2,3


    Otherwise, how are you going to take "half" of
    nine numbers? The ninth number doesn't split
    very well. :)

    Also, I believe you meant for the "4" to be
    at the beginning of the swapped string?

    I'd use std::list and list.splice();
    it makes this kind of thing a breeze:

    #include <iostream>
    #include <list>

    int main()
    {
    // Make and load your list:
    std::list<char> List;
    for (char i = 0; i<8; ++i)
    List.push_back(i);

    // Get an iterator to fifth element:
    std::list<char>::iterator i;
    i = find(List.begin(), List.end(), 4);

    // Splice fifth-through-eighth elements to beginning:
    List.splice(List.begin(), List, i, List.end());

    // Print results and return:
    for (i = List.begin(); i != List.end(); ++i)
    std::cout << static_cast<int>(*i) << " ";
    std::cout << std::endl;
    return 0;
    }

    --
    Cheers,
    Robbie Hatley
    Tustin, CA, USA
    email: lonewolfintj at pacbell dot net
    web: home dot pacbell dot net slant earnur slant
     
    Robbie Hatley, Jul 12, 2004
    #9
    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. Jerry C.
    Replies:
    8
    Views:
    278
    Uri Guttman
    Nov 23, 2003
  2. Kruno Saho
    Replies:
    0
    Views:
    168
    Kruno Saho
    Apr 7, 2013
  3. Dave Angel
    Replies:
    0
    Views:
    145
    Dave Angel
    Apr 7, 2013
  4. rusi
    Replies:
    0
    Views:
    133
  5. Miki Tebeka
    Replies:
    0
    Views:
    95
    Miki Tebeka
    Apr 7, 2013
Loading...

Share This Page