-2

Basically, the copy string function is supposed to copy 1 string to another. The output for both strings is Hello World! Why does this actually work though because I am only passing in the value of these strings? I'm not passing by reference or anything.

My second question is why do I have to include string.h but not iostream.h? Why does the .h part only have to be there to include the string header file? Why is iostream so special it doesn't need a .h extension?

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

void copyString(char[] stringToCopyTo, char[] stringToCopy);

int main(){

    char string1[] = "Hello World!";
    char string2[80];

    copyString(string2, string1);

    std::cout << "String1: " << string1 << "\n";
    std::cout << "String2: " << string2 << "\n";

    return 0;
}

void copyString(char stringToCopyTo[], char stringToCopy[]){
    stringToCopyTo = stringToCopy;
}
  • Your code has undefined behaviour, since `string2` is not null-terminated, and in fact uninitialized. – Kerrek SB May 28 '14 at 00:26
  • It works thanks to the magic of undefined behavior, it's really useful for solving just about anything because one possible outcome is that your program actually works as expected! – user657267 May 28 '14 at 00:28
  • Ah, ignore those brackets lol. I copied it slightly before I re-edited the code. – Dominic Oryema May 28 '14 at 00:28
  • 3
    @Dominic Oryema: No, we'll not "ignore those brackets". You will have to re-post the exact real code. Post the exact output as well. This code can "work" only by accident, but it is kinda hard to believe that this code can produce the "proper" output, even by accident. – AnT stands with Russia May 28 '14 at 00:46
  • `char[] str` looks like Java. Be aware that C arrays behave little like Java arrays. – Potatoswatter Jun 09 '14 at 05:13

3 Answers3

5

It doesn't work. The second std::cout line invokes undefined behavior, since you're calling it on an uninitialized array. It appears to work because of the way your array and your string are laid out in memory, std::cout is probably actually printing out string1 again, and string2 is filled with something non-printable.

You're correct, the copyString function doesn't do anything observable outside that function. It just re-assigns some local variables. However, you're just assigning one pointer to another, it does not copy the string.

For the headers, the C standard library uses headers that end in .h. C++ standard library headers do not. iostream is in the C++ standard library, string.h is in the C standard library. However, when using C headers in C++, use their C++ equivalent, usually the header name pre-pended by c, in this case cstring. Note, no .h.

But, since you're using C++, you should be using C++ strings instead, then your function will do what you want it to:

#include <iostream>
#include <string> // C++ string header

// Strings passed by reference
void copyString(std::string& stringToCopyTo, std::string& stringToCopy);

int main(){

    std::string string1 = "Hello World!";
    std::string string2;

    copyString(string2, string1);

    std::cout << "String1: " << string1 << "\n";
    std::cout << "String2: " << string2 << "\n";

    return 0;
}

// Strings passed by reference
void copyString(std::string& stringToCopyTo, std::string& stringToCopy){
    stringToCopyTo = stringToCopy;
}
Collin
  • 11,977
  • 2
  • 46
  • 60
3

Firstly, your code simply does not compile, since your copyString function declaration is syntactically incorrect. You managed to use the proper syntax in function definition, but completely botched the declaration. Are you posting real code?

Secondly, what you are passing into the function is char * pointers. In function parameter list char stringToCopyTo[] is equivalent to char *stringToCopyTo. So, you are not passing your arrays "by value", as you seem to believe. Arrays in C++ are not copyable. They cannot be passed by value.

Thirdly, inside the function you are simply assigning local pointers to each other. The strings do not get copied. Nothing really gets copied. Which means that your code does not "work" as intended. Array string2 remains uninitialized. It contains garbage and the code outputs garbage. (Formally, the behavior is undefined.)

So, it is not clear what you mean by "works" in your question, and where you see "string swap" here.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • I assumed he meant that the output was the same as if the string copy was successful. – Mooing Duck May 28 '14 at 00:43
  • 1
    @Mooing Duck: I highly doubt it is possible in practice (even though it is, of course, possible in theory). Most likely the code the OP posted is different from the code the OP actually ran. (Especially if one takes into account the fact that the posted code is not compilable.) – AnT stands with Russia May 28 '14 at 00:45
2

The copyString function has no effect. Inside that function , stringToCopy etc. are pointers, and you just move around the pointer values without changing the characters being pointed to.

Inside main, you don't initialize string2. So doing cout << string2 causes undefined behaviour. What you are seeing is the results of display uninitialized variables.

Fix by doing:

char string2[80] = "";

Note - your function prototype is wrong; it must be char name[], not char[] name. I guess this was a typo (or some sort of compiler extension).


Regarding the header files: the standard C++ headers include <iostream> and <cstring> (and <string>). Anything ending in .h is implementation-defined.

A common behaviour is for the names of C-library headers, that #include <string.h> behaves like #include <cstring> along with injecting all identifiers from cstring into the global namespace. Your program does not actually use anything from this header though, so you could remove it.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365