• Advertisement
Sign in to follow this  

Is strcpy worth it?

This topic is 4523 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Here's an example of how i've been saving char* in member variables:
void myFunction( char* name )
{
    m_name = name;
}

But I've noticed other programmers go to this trouble
char* m_name[16];

void myFunction( char* name )
{
    strcpy( m_name, name );
}

Whats the point of this? fixed allocation size for the char* variable? I've seen some sources claim the strcpy way is slower..... Thanks Simon

Share this post


Link to post
Share on other sites
Advertisement
If you're using C++, you shouldn't be doing either of those things. Just use std::string.

Having said that, the reason is that if you just do:
string_1 = string_2;
(where both strings are char*-style strings), then you will only have a single copy of the actual string data in memory. If that data then gets changed (or the memory is released), then both strings appear to change (the variables haven't actually been altered - they still point to the same bit of memory - but the data that is in that memory has changed, so both strings have changed)

Not a good explanation, but I'm pushed for time (I expect someone else will come along and write something clearer).

Anyway, if you're in C++, just use std::string - it deals with all of that stuff for you, so you can just use the normal assignment (=) operator (and also other normal operators like the comparison operators).

John B

Share this post


Link to post
Share on other sites
m_name = name is Bad. You're assigning pointers, not copying memory. Here's a quick primer on the difference:

Strings have to occupy a span in memory. If you have a 125 character string, its going to occupy 126 bytes (1 byte for it's null terminator). A pointer is, on 32 bit machines, 4 bytes wide. The pointer itself does not contain the string, but the address in memory of where the string begins.

So, strcpy dereferences the pointers, to find the strings, and copys the actual character data ack and forth. The reason you do not just assign the pointer to the strings to an object member data, is because you are just creating extra aliases back to the original string, and an attempt to change the string in one object would change that string in all of the objects.

Also, if the string were contained on the stack for some reason, that string would disappear when the function ended.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You also probably want to use strncpy() if you aren't going to check the length of the input string. Something like:

#include <assert.h>
#include <string.h>

/* Just being explicit about filling m_name with '\0'. */
/* The last element should always be '\0' so we always have a valid string. */
char m_name[16] = {0};

void myFunction(char *name) {
/* Never overwrite the last element of m_name */
/* It should always be '\0' so that m_name is always a string */
strncpy(m_name, name, sizeof m_name - 1);
assert(m_name[sizeof m_name - 1] == '\0');
}


Another option is to dynamically allocate space:

#include <stdlib.h>
#include <string.h>

char *m_name = NULL;

int main(void) {
m_name = malloc(1);
if (!m_name) { return EXIT_FAILURE; }
m_name[0] = '\0'; /* Empty string */
return EXIT_SUCCESS;
}

int myFunction(char *name) {
char *temp = realloc(m_name, strlen(name) + 1);
if (!temp) { return -1; /* -1 for failure */ }
strcpy(m_name, name);
return 0; /* 0 for success */
}

Share this post


Link to post
Share on other sites
Quote:
Original post by JohnBSmall
If you're using C++, you shouldn't be doing either of those things. Just use std::string.

Anyway, if you're in C++, just use std::string - it deals with all of that stuff for you, so you can just use the normal assignment (=) operator (and also other normal operators like the comparison operators).

John B


Quoted for emphasis.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
You also probably want to use strncpy() if you aren't going to check the length of the input string. Something like:
*** Source Snippet Removed ***
Another option is to dynamically allocate space:
*** Source Snippet Removed ***

Of course as suggested before, you should use std::string or (if you were up to it, although std::string will likely still be better) your own string class that handles memory management.

Share this post


Link to post
Share on other sites
lol i'm actually a memmove person, even for c strings and
even if i'm using C++. it's really a useful all-purpose
copy function; and i use it alot programming the ol' Win32.
and personally, i find working with std::strings in Windows
programming rather cumbersome.

Share this post


Link to post
Share on other sites
Quote:
Original post by Inmate2993
m_name = name is Bad. You're assigning pointers, not copying memory.

Unless that is exactly the behavior you desire.

Quote:
... you are just creating extra aliases back to the original string, and an attempt to change the string in one object would change that string in all of the objects.

The Win32 API employs this technique liberally, and although it's pretty much kept to C code, there's not too much difference in the method of passing a std::string &, or even a std::string const *.

EDIT: I'm not referring to data members of classes, as many times you'd want the class to retain its own copy.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement