2

I am passing an string or a char array to a function and swapping them but losing the first char array's value for some reason. Here is my code:

void foo(char* a, char* b){

         char* temp;

         temp = new char[strlen(a)+1];
         strcpy(temp, a);
         strcpy(a, b);
         strcpy(b, temp);

         delete[] temp;
}

So in foo the function gets passed two pointers and the are attempted to be swapped. Here is the main function. There may be a problem with the passing of the variable, but the compiler did not give me an issue.

int main(){

         char a[] = "First";
         char b[] = "Last";

         std::cout << "A Before: "<< a << "\n";
         std::cout << "B Before: " << b << "\n\n";

         foo(a, b);

         std::cout << "A After: "<< a << "\n";
         std::cout << "B After: "<< b << "\n\n";

         return 0;
}

The output I am getting is as follows:

A Before: first
B Before: last

A After: 
B After: first

Now I have tested the values of the strings while in the function during the strcpy's and turns empty after the final strcpy, which means, or at lest I think, that the problem lies within the pointers to the original variables. It could be a chain reaction type of thing where all of the pointers are pointing to the "a" and it confuses the program.

Any help would be appreciated, also why this is happening would be very useful as well.

Saulius
  • 21
  • 1
  • 9
  • `std::string` has swap capabilities. – chris Sep 13 '13 at 01:06
  • 6
    I would say you have undefined behavior here `strcpy(b, temp);` – this Sep 13 '13 at 01:07
  • I tried using strncpy(b, temp, strlen(temp)), which gives the output: A After: last / B After: firstlast. Why would that be? – Saulius Sep 13 '13 at 01:13
  • @SauliusGrybas Hint, what are the sizes of a and b. – this Sep 13 '13 at 01:15
  • For some reason when you change the strlen of "b" it changes the strlen of "a". When I strcpy temp into b the strlen of "a" turns into zero, but before that its the length of "b". – Saulius Sep 13 '13 at 01:40

2 Answers2

1

Because your string a is longer than b.So strcpy does not work as you expect in line:

strcpy(b, temp);

Tips:

  • Use strncpy instead of strcpy
  • Use c++ Strings instead of the c style string.Then you can swap them with a.swap(b);
prehistoricpenguin
  • 6,130
  • 3
  • 25
  • 42
  • I tried using strncpy(b, temp, strlen(temp)), which gives the output: A After: last / B After: firstlast. Why would that be? – Saulius Sep 13 '13 at 01:40
  • @SauliusGrybas `temp` is also longer than `b`, `b` don't have enough spaces to hold `temp`, you may try `strncpy(b, temp, strlen(b))` – prehistoricpenguin Sep 13 '13 at 01:46
  • I have tried that as well, and actually this is where it gets weird. If I change the strlen of b to 6 or greater, the strlen of "a" automatically turns into 0. Otherwise, the strlen of b will stay at 9. Its a very odd situation. The two are some how dependant on each other. – Saulius Sep 13 '13 at 01:58
  • @SauliusGrybas Yes, on my computer the address of `a` is just 5 bytes after the start address of 'b',the same size with the length of string `a`.so when you use `printf` with `b` after your swap, it will regard the first `\0` character that behind start address of `b` as the end of that string,actually it's the end of string `a`, then you get `firstlast` as output. – prehistoricpenguin Sep 13 '13 at 02:11
  • @SauliusGrybas Because `a` and `b` are declared in two continual statements, so the common memory layout is: [memory for a][memory for b]: the memory goes from high to low,so `a` is just 5(the size of a is 5 bytes) bytes after the start address of 'b'. – prehistoricpenguin Sep 13 '13 at 02:23
  • Awesome thanks for the tip. I figure you just need to then realloc a. – Saulius Sep 13 '13 at 02:34
  • @SauliusGrybas You may not use realloc a, because a is an array.General Speaking, we do not have any scenarios to swap two c style strings。 – prehistoricpenguin Sep 13 '13 at 02:50
1

The problem is your array sizes happen to be such that you are clobbering your stack; fortunately, for you, the effect is simply to place a null byte in the first character of a, making it an empty string.

#include <iostream>
#include <string.h>

void foo(char* a, char* b){
         char* temp = new char[strlen(a)+1];

         strcpy(temp, a);
         std::cout << "temp = " << temp << " a = " << a << " b = " << b << std::endl;

         strcpy(a, b);
         std::cout << "temp = " << temp << " a = " << a << " b = " << b << std::endl;

         strcpy(b, temp); // this copies 6 bytes to b, which puts a 0 in the first byte of a.
         std::cout << "temp = " << temp << " a = " << a << " b = " << b << std::endl;

         delete[] temp;
}

int main() {
     char a[] = "First";
     char b[] = "Last";

     std::cout << "a size is " << sizeof(a) << std::endl;
     std::cout << "b size is " << sizeof(b) << std::endl;

     std::cout << "address of a[0] is " << (void*)&a[0] << std::endl;
     std::cout << "address of b[0] is " << (void*)&b[0] << std::endl;

     foo(a, b);

     std::cout << "A After: "<< a << "\n";
     std::cout << "B After: "<< b << "\n\n";
}

http://ideone.com/fDvnnH

a size is 6
b size is 5
address of a[0] is 0xbfec5caa
address of b[0] is 0xbfec5ca5
temp = First a = First b = Last
temp = First a = Last b = Last
temp = First a =  b = First
A After: 
B After: First

You might want to investigate std::string or look at using std::strncpy

kfsone
  • 23,617
  • 2
  • 42
  • 74