473,411 Members | 1,980 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,411 software developers and data experts.

string copy. this one works, but why that one doesn't?

I'm confused about the two ways of string copy below. The first one
(two functions) works; the second doesn't. Can anybody explain the
reason to me? Thanks a lot.

#include <stdio.h>
/*this one works well
void copy (char *s, char *t)
{
int i = 0;

while ((*t++ = *s++) != '\0')
;
}

main ()
{
char *s = "abcde";
char *t;
copy (s, t);
printf ("%s\n", t);
}
*/
//put all of them together in main, why "Segmentation fault"?
main ()
{
char *s = "abcde";
char *t;

int i = 0;

while ((*t++ = *s++) != '\0')
;
printf ("%s\n", t);
}

Aug 5 '06 #1
6 1516
Gary said:
I'm confused about the two ways of string copy below. The first one
(two functions) works; the second doesn't. Can anybody explain the
reason to me? Thanks a lot.
In C, all arguments to a function are evaluated, and their values passed to
the function, which receives those values in its local parameter objects.
No matter how the function changes those local copies, the original
expressions evaluated in the call are not affected in the slightest.
#include <stdio.h>
/*this one works well
void copy (char *s, char *t)
{
int i = 0;

while ((*t++ = *s++) != '\0')
;
When this loop is complete, both t and s point to the end of the string, not
the beginning.
}
But now t and s have ceased to exist, so it hardly matters.
>
main ()
{
char *s = "abcde";
char *t;
copy (s, t);
This is an error. t doesn't point to any storage. Everything Has To Be
Somewhere. When you make a copy of s, that copy has to be put somewhere.
But you haven't specified anywhere to put it.

But if we pretend you'd written:

char buf[6];
char *t = buf;

that would point t at enough storage to hold a copy of "abcde".
printf ("%s\n", t);
}
*/
//put all of them together in main, why "Segmentation fault"?
main ()
{
char *s = "abcde";
char *t;
Let's fix this to:

char buf[6];
char *t = buf;
int i = 0;

while ((*t++ = *s++) != '\0')
;
Just like before, you're walking these pointers to the end of the string.
But this time, they don't magically vanish, leaving the originals as they
were before your copy() call. This time, they're /still/ at the end of the
string.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Aug 5 '06 #2
Gary wrote:
I'm confused about the two ways of string copy below. The first one
(two functions) works; the second doesn't. Can anybody explain the
reason to me? Thanks a lot.

#include <stdio.h>
/*this one works well
void copy (char *s, char *t)
{
int i = 0;

while ((*t++ = *s++) != '\0')
;
}

main ()
{
char *s = "abcde";
char *t;
copy (s, t);
printf ("%s\n", t);
}
*/
//put all of them together in main, why "Segmentation fault"?
main ()
{
char *s = "abcde";
char *t;

int i = 0;

while ((*t++ = *s++) != '\0')
;
printf ("%s\n", t);
}
In addition to what Richard Heathfield already wrote, I think it should
be emphasized that the first method of copying is also broken. The
fact that it worked when you tried it was sheer blind luck and can't be
depended on. The reason is that t is uninitialized. When you declare
"char *t", you are telling the program: "temporarily give me a block
of memory big enough to hold the address of a char." The program gives
you that block, but you never say what address to store in that block.
Kind of like buying a cellphone at a yard sale, then immediately trying
to use it's speed dial to call your friend. A more correct way to do
the first version would be

#include <stdio.h>
void copy (char *s, char *t)
{
while ((*t++ = *s++) != '\0')
;
}

main ()
{
char *s = "abcde";
char t[6];

copy (s, t);
printf ("%s\n", t);
}

Aug 5 '06 #3
Snis Pilbor said:

<snip>
>
In addition to what Richard Heathfield already wrote, I think it should
be emphasized that the first method of copying is also broken. The
fact that it worked when you tried it was sheer blind luck and can't be
depended on. The reason is that t is uninitialized.
For the record, I did actually point this out in my earlier reply. But
you're right that it should be emphasised.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Aug 5 '06 #4
Gary posted:
I'm confused about the two ways of string copy below. The first one
(two functions) works; the second doesn't. Can anybody explain the
reason to me? Thanks a lot.

#include <stdio.h>
/*this one works well
void copy (char *s, char *t)

It's customary to put the destination buffer first, and then the source
buffer next (this is how the C Standard Library does it).

Also, make use of "const":

void copy(char *dest, char const *source)
{
int i = 0;

What's that doing there? You never use it.

while ((*t++ = *s++) != '\0')
;
}

Your algorithm works OK.
main ()
{
char *s = "abcde";
char *t;

A floating-point type stores a floating-point number.

An integer type stores an integer number.

A pointer type stores a memory address.

If you don't initialise a local variable, then it contains garbage. In your
code snippet, you don't initialise "t" and so it contains a garbage memory
address. It may contain the memory address 0x2325ADD234, which points to
Operating System memory which you're not allowed play around with.

The solution would perhaps be something like the following:

char const source[] = "abcde";

char dest[sizeof source];

copy(dest,source);

--

Frederick Gotham
Aug 6 '06 #5
In an ideal world, when you write a function, it's really nice if:

(1) The function checks its input arguments for plausibility.

(2) The function knows the size and validity of where it is supposed to
put its output.

(3) The function does something reasonable with invalid input.

-----

Now in the wild world of C, these things are not always knowable.

But you could at least check the input and output parameters to ensure
they're not NULL. That will catch many otherwise hard to find fatal
errors. In some C's, there are (non-standard) functions that can tell
you if a pointer is pointing to writeable memory, that can also be a
very helpful thing to try calling.

If you want to be really careful, and you know your strings are going
to be plain ASCII text, of reasonable length, you could even scan the
input string and not copy anything that has a character 127 or a
length longer than some reasonable value you choose. That will catch a
lot of unset inputs.

And it's a really good idea to supply the length of the output place to
your copy function, so you don't go stomping all over memory. See
strncpy.

And as to what you do with invalid input, please don't silently return,
do something reasonable, like call some global error reporting
function.

Aug 6 '06 #6
"Gary" <xg****@gmail.comwrites:
I'm confused about the two ways of string copy below. The first one
(two functions) works; the second doesn't. Can anybody explain the
reason to me? Thanks a lot.
You got lucky/unlucky. You have undefined bahaviour because you have not
allocated space for "t" to store a string. In addition you have used
printf to print a string at the end of "t" in the "single function"
solution. See below.

>
#include <stdio.h>
/*this one works well
void copy (char *s, char *t)
{
int i = 0;

while ((*t++ = *s++) != '\0')
;
}

main ()
{
char *s = "abcde";
char *t;
copy (s, t);
"t" is not allocated memory to store a string.
printf ("%s\n", t);
}
*/
//put all of them together in main, why "Segmentation fault"?
main ()
{
char *s = "abcde";
char *t;
*oops*. You have declared a character pointer, but havent told the
program what it points to. Did your compiler not tell you this?
>
int i = 0;

while ((*t++ = *s++) != '\0')
;
printf ("%s\n", t);
You should probably do something like

char *p=t;
while(*p++=*s++);
printf("%s\n",t);

Also, what's "i" for? The rest you can figure out I guess. Use a
character array or malloc/free.
Aug 6 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

42
by: Edward Diener | last post by:
Coming from the C++ world I can not understand the reason why copy constructors are not used in the .NET framework. A copy constructor creates an object from a copy of another object of the same...
16
by: Khuong Dinh Pham | last post by:
I have the contents of an image of type std::string. How can I make a CxImage object with this type. The parameters to CxImage is: CxImage(byte* data, DWORD size) Thx in advance
17
by: jake1138 | last post by:
Here is a function I have to get a number at the end of a string. I'm posting this in case it proves helpful to someone. Comments are welcome. int getnum(char *str) { char buffer; char *buf...
19
by: Paul | last post by:
hi, there, for example, char *mystr="##this is##a examp#le"; I want to replace all the "##" in mystr with "****". How can I do this? I checked all the string functions in C, but did not...
10
by: cppdev | last post by:
Hi All! I want to clear the string contents from sensitive information such as passwords, and etc. It's always a case that password will appear as string at some point or another. And i feel...
25
by: electrixnow | last post by:
in MS VC++ Express I need to know how to get from one comma delimited text string to many strings. from this: main_string = "onE,Two,Three , fouR,five, six " to these: string1 =...
15
by: Lighter | last post by:
I find a BIG bug of VS 2005 about string class! #include <iostream> #include <string> using namespace std; string GetStr() { return string("Hello");
34
by: Larry Hastings | last post by:
This is such a long posting that I've broken it out into sections. Note that while developing this patch I discovered a Subtle Bug in CPython, which I have discussed in its own section below. ...
111
by: Tonio Cartonio | last post by:
I have to read characters from stdin and save them in a string. The problem is that I don't know how much characters will be read. Francesco -- ------------------------------------- ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.