tags:

views:

216

answers:

7
+2  Q: 

String statements

Talking about strings in C++, what is the difference between the following statements: s1=s2 and strcpy (s1, s2)? Supposing that s1 and s2 are (original version: type 'char', as revised) type char *.

+3  A: 

Difference between char and char* and char* null terminated string:

At first your question asked about strcpy and char. char holds a single character. Each char has an address. The address of a char is char*

It is very common in C/C++ to use a char* to point to the first character of a null terminated character array. We consider a null terminated character array a null terminated string.

To know when the string contained inside the array ends, a null terminated character is added to the end of the string.

Null terminated strings:

const char *p = "hello";
const char *s = "world";
p = s;

Both p and s hold a memory address to the first element in the array of the string literal. When you say p = s you are simply changing what the p variable holds to be the s memory address value that s holds.

So above originally p may hold 0x94749248, and s may hold 0x84811409. And after the assignment p = s, p and s hold 0x84811409.

The actual array of characters are stored at memory address 0x84811409

strcpy:

strcpy works on char* not char. By char* I mean a pointer to the first element of an array of chars, representing a null terminated string.

The following actually copies the data into szBuffer.

char szBuffer[512];
char *p = "hello world!";
strcpy(szBuffer, p);

Nowp holds a memory address of the string literal "hello world!" and szBuffer holds its own copy of all of the characters.

szBuffer after the call to strcpy still holds the same 512 memory addresses. It's just that they have been filled with the values starting at *p.

STL strings:

strings in C++ usually refer to STL strings.

#include <string>

std::string s = "hi";
Brian R. Bondy
@Brian: Thanks:)
Brian R. Bondy
+15  A: 

Given:

char s1, s2;
...
s1 = s2;          // Assigns value in s2 to s1
strcpy(s1, s2);   // Error detected by compiler; strcpy() takes char pointers

Given:

char *s1, *s2;
...
s1 = s2;         // s1 points to the same 'string' that s2 does
strcpy(s1, s2);  // the space pointed to by s1 contains the same
                 // characters as the space pointed to by s2.

In the second case (pointers), there are a number of caveats about making sure you have enough space allocated for the actual string - as opposed to the pointers. The triple dots indicate where there is some work to be done to ensure things are initialized.

Jonathan Leffler
+1 SOOOOOOOOOOOOOO much more succinct and comprehensible than my own rambling answer :)
Binary Worrier
Don't forget the memory leak `s1 = s2` causes if s1 owns allocated memory.
Bill
@Bill: that's one of the caveats... :D
Jonathan Leffler
A: 

if s1 and s2 are of type char*, then
char* s1 = "Hello";
char* s2 = "World"; s1 = s2; // now s1 points to World.

now, if char s1[] = "Hello";
char s2[] = "World";
then, strcpy(s1, s2); // now s1 contains Hello .
char* s1 = "Hello";
char* s2 = "World";
then, strcpy(s1, s2); // this is undefined behaviour.

Jagannath
A: 

I assume you mean "s1 and s2 are type char*", since the arguments to strcpy are type char*. This is an important distinction, because it means that s1 and s2 are pointers. (That's how strings are represented in C, pointers to a series of characters)

s1 = s2 assigns s1 to point to the same location as s2. Since they both now refer to the same location, they are exactly the same string, and any change made to the string from one pointer appears when using the other pointer as well.

strcpy(s1, s2) assumes that s1 already points to a memory block at least as large as the string pointed to by s2. It copies the contents of the memory block pointed to by s2 into the memory block pointed to by s1. Afterwords, the strings s1 and s2 have the same contents, but are still two different strings in two different locations and can be modified independently.

Tyler McHenry
A: 

I simply want to expand on Jonathan Leffler's answer slightly.

When you do s1 = s2, the following is true:

s1[0] = 'h';
s2[0] = 'q';
s1[0] == 'q';
s2[0] == 'q';

When you use strcpy, the following is true:

s1[0] = 'h';
s2[0] = 'q';
s1[0] == 'h';
s2[0] == 'q';
sharth
Did you mean the initial 's1 == s2' to have a double equals? The question probably uses a single equals (assignment)...it doesn't mention comparison directly.
Jonathan Leffler
Thanks for catching that. I did mean to have assignment.
sharth
+1  A: 

There are several things wrong with your question, I'll try and clarify.

If S1 and S2 are of type char, then they're not strings, they're single characters, not strings of characters.

For S1 & S2 to be strings, they'd need to be declared like, char* s1 = ; char* s2 = ;

char* S1; says that S1 is not a character, but instead will point to a location in memory, and it will interpret what ever is stored there as a character. In classic C strings are represented as a sequence of characters in memory (stored contiguously, one beside the other). The end of the string is marked by the last character, which must be Zero (hence C strings are also called Zero Terminated Strings).

This idiom for defining strings can also be done in C++, but C++ has a specific string type declared in the Standard Template Library.

So, for the second part of your question, whats the difference between strcpy(S1, S2), and S1 = S2.

Firstly, for this question to make sense S1 and S2 must be character points (as shown in the first point). The difference is strcpy copies the string from one memory location to another (it literally moves through each character and copies it to the other memory location) while "S1 = S2", simply gets S1 to point to the same memory location that S2 points to e.g. Sample strcpy function, NB this code may not compile

function strcpy(char *destination, char* source)
{
   while(*source != 0)
   {
      *destination = *source; /* assign this character to destination */
      destination++; /* move the destination pointer to the next location*/
      source++;      /* move the source pointer to the next location */
   }
   *destination = 0; /* put a zero terminator into destination at the end of the string */
}

}

"S1 = S2" is dangerous because if you then add some characters to the string at S2, you will see those changes in S1, because they are both pointing at the same string.

NB strcpy expects there to be enough memory allocated at S1 to hold the contents of S2 PLUS an extra character for the Zero Terminator.

Hope this helps, if you need clarification on anything, just post a comment.

Binary Worrier
A: 

The difference is that s1 = s2 copies pointers (to contents) and strcpy(s1, s2) copies the contents.

Let's look at the following code:

char* s1 = (char*)malloc(12*sizeof(char));
strcpy(s1, "Hello World");

s1 now points to the memory address, let's say 0x0123 with the contents of "Hello World".

char* s2;
s2 = s1;

Now s2 points to the same memory location that s1, that is 0x0123.

char* s3 = (char*)malloc(12*sizeof(char));
strcpy(s3, s1);

In this case s3 points to a distinct memory address, let's say 0x0540 and has a copy of the contents of s1, that being "Hello World".

Contents wise s1, s2 and s3 look the same. The interesting thing happens when you do the following:

free(s1);
free(s2);
free(s3);

The first call to free is valid, since the memory was properly allocated and all. The second call to free is invalid (and will probably crash you app), since the memory at 0x0123 was already freed. The third call to free is valid since the memory at 0x0540 is was not freed yet.

As you can see it depends on the distinct use. Copying the pointer is much faster than copying the contents but it needs clear definition of who is in change of the memory and a proper definition of the lifetime of the memory.

Since this question is tagged with c++, I will give the additional advice:

By default use std::string. It removes many pitfalls when using strings. Yes, it is slower but 95% of the time you will never notice and in those cases where you do, you can think of a better way to do things.

Sean Farrell