1

I'm wondering if it's possible to swap the contents of two C++ arrays that are of different sizes (without using any predefined C++ functions)? My code is as follows:

#include <iostream>
#include <string>

using namespace std;  

void swapNames(char a[], char b[])
{

    //can be done with one temp; using two for clarity purposes 
    char* temp = new char[80];
    char* temp2 = new char[80];
    int x = 0;

    while(*(b+x)!='\0')
    {
        *(temp+x) = *(b+x);
        x=x+1;
    }

    x=0;
    while(*(a+x)!='\0')
    {
        *(temp2+x) = *(a+x);
        x=x+1;
    }

    x=0;    
    while(*(temp2+x)!='\0')
    {
        *(b+x) = *(temp2+x);
        x=x+1;
    }

    x=0;
    while(*(temp+x)!='\0')
    {
        *(a+x) = *(temp+x);
        x=x+1;
    }
}

int main()
{
    char person1[] = "James";
    char person2[] = "Sarah";

    swapNames(person1, person2);

    cout << endl << "Swap names..." << endl;
    cout << endl << "Person1 is now called " << person1;

    cout << "Person2 is now called " << person2 << endl;;
}

My initial idea was to pass in references to person1 and person2 themselves, store the data in temp variables, delete the memory allocated to them, and link them to newly created arrays with the swapped data. I figured this would avoid predefined memory limits. It seems, though, that passing in references(&) to arrays is very much not allowed.

The above works fine if person1 and person2 are of the same size. However, once we have names of different sizes we run into problems. I assume this is because we can't alter the memory block we allocated when we initially created person1 and person2.

Also, is it possible to create a new array in C++ without predefining the size? IE a way to create my temp variables without placing a limit on their sizes.

3 Answers3

5
char person1[] = "James";

is just a shorthand for:

char person1[6] = "James";

You cannot later store more than 6 characters in person1. If what you really want are strings of varying lengths, I would suggest ditching C style strings in favor of the std::string standard library type:

#include <string>
#include <algorithm>

std::string person1 = "James";
std::string person2 = "Sarah";

swap(person1, person2);

If your book teaches C style strings before std::strings, you should consider getting a new book.

Community
  • 1
  • 1
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • Seeing your clarification of the similarities between person1[] and person1[6] is helpful. It really makes the abstract concept clearer. Thank you. With regard to std::string, I was more trying to figure out if it was possible to do the swap with char arrays. I'm starting to think it's probably not. – Ensign Variable Oct 14 '12 at 15:03
  • @EnsignVariable If you want to use arrays instead of `std::string` use [`std::array`](http://en.cppreference.com/w/cpp/container/array). There is a specialization of `std::swap` for this container, so 2 `std:array`s of the same size and type can be swapped. – Praetorian Oct 14 '12 at 15:14
1

References to arrays are allowed, as long as the array is fixed size.

There's an easy answer instead of all the complex things you are considering. Just use a vector.

vector<char> a;
vector<char> b;
...
a.swap(b);

What could be easier?

Also vectors are the answer to your question, 'Also, is it possible to create a new array in C++ without predefining the size?'. You can create a vector and then resize it later (which is almost the same thing).

john
  • 85,011
  • 4
  • 57
  • 81
  • Thanks for that :). I was more trying to figure out if it was possible just using char arrays in an effort to better understand how arrays work in C++. – Ensign Variable Oct 14 '12 at 15:00
  • @EnsignVariable In that case the answer is no. Arrays are not first class types in C/C++ (for instance you cannot assign them). – john Oct 14 '12 at 15:45
0

You should always prefer container classes over raw arrays. But, if you absolutely must use an array, you can certainly accomplish swapping without resorting to dynamically allocating the temporary array. Use templates to statically determine the type and size of the arrays being passed into the swap function.

#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>

template<typename T, size_t N>
void swap_arrays( T(&left)[N], T(&right)[N] )
{
  T temp[N];

  // copy left to temp
  std::copy( std::begin(left), std::end(left), std::begin(temp) );
  // copy right to left
  std::copy( std::begin(right), std::end(right), std::begin(left) );
  // copy temp to right
  std::copy( std::begin(temp), std::end(temp), std::begin(right) );
}

template<typename T, size_t N>
void swap_and_print( T(&left)[N], T(&right)[N] )
{
  std::cout << "\nBefore swapping: \n";

  std::cout << "  Left:";
  std::for_each( std::begin(left), std::end(left), 
                 []( T const& t ) { std::cout << " " << t; } );
  std::cout << "\n  Right:";
  std::for_each( std::begin(right), std::end(right), 
                 []( T const& t ) { std::cout << " " << t; } );

  swap_arrays( left, right );

  std::cout << "\nAfter swapping: \n";

  std::cout << "  Left:";
  std::for_each( std::begin(left), std::end(left), 
                 []( T const& t ) { std::cout << " " << t; } );
  std::cout << "\n  Right:";
  std::for_each( std::begin(right), std::end(right), 
                 []( T const& t ) { std::cout << " " << t; } );
}

int main()
{
  int foo1[] = {1,2,3,4,5};
  int bar1[] = {6,7,8,9,10};

  swap_and_print( foo1, bar1 );

  char foo2[] = "James";
  char bar2[] = "Sarah";

  swap_and_print( foo2, bar2 );
}

Output:

Before swapping: 
  Left: 1 2 3 4 5
  Right: 6 7 8 9 10
After swapping: 
  Left: 6 7 8 9 10
  Right: 1 2 3 4 5
Before swapping: 
  Left: J a m e s �
  Right: S a r a h �
After swapping: 
  Left: S a r a h �
  Right: J a m e s �

Note: The weird character at the end of the second example is because the inputs are char arrays that include the terminating null character; and what you're seeing is its visual representation (since the code is printing it out as a character).

Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • Thanks for introducing me to templates :) I was leaning more to doing as much as possible with arrays, though. Cool implementation nonetheless. – Ensign Variable Oct 14 '12 at 20:02