2

Here's my code...

char* m1;
char* m2 = "sth";
strcpy(m1, m2);

That code threw run-time errors, so I tried...

char m1[];
char m2[] = "sth"; 

That can run with no errors. However, I want to use...

char* s

What sould I do?

10
  • 3
    strcpy requires enough space at the destination. Any reason you can't use std::string? Commented Sep 17, 2012 at 8:57
  • I would recommed.. char *m1 = malloc( sizof(char) * (strlen(m2) + 1)); and declare m2 first. then you dont need to worry about magic numbers. Commented Sep 17, 2012 at 9:00
  • @MarsRover: sizeof(char) is redundant as it is always 1 by definition. Commented Sep 17, 2012 at 9:01
  • I like putting in the sizeof(char) as it gets optimized out and improves code readability Commented Sep 17, 2012 at 9:02
  • @Minion91: you could make a case for putting sizeof(*m1), but sizeof(char) is just needless clutter. Commented Sep 17, 2012 at 9:04

5 Answers 5

2

You should allocate memory for m1. For example

char* m1 = new char[4];
char* m2 = "sth";
strcpy(m1, m2);
// so smth with m1
delete[] m1;

But since you write on C++, why you not use std::string?

Sign up to request clarification or add additional context in comments.

1 Comment

The last sentence (of an answer!) shouldn't be a question although the intent of the (rethorical) question is clear.
1

Problem is you are not allocating any memory to store the result of the strcpy method. You need:

char* m1 = (char *) malloc(sizeof(char) * 4) /* 4 being the size of 3 chars + trailing \0 */
char* m2 = "sth";

Than you can do the strcpy

And in the end you have to free any dynamically allocated memory a.g.

free(m1)

m2 is allocated statically and doesn't has to be freed.

4 Comments

Question is tagged as C++, not C.
Then, I have to FREE my m1. haven't I?
yes. but you should check if you want C or C++, as your code is mostly C, but is tagged C++. you can look into the c++ string method, unique/shared pointers.
Thanks guy, I forgot to cast (char *) and replied something stupid as well.
1

In C++ you would rather do:

// don't forget to #include <string>
std::string m1;
std::string m2 = "sth";
m1 = m2;

if you then need a const char* (e.g., for some API call) you can get one

const char* str = m1.c_str();

Problem gone.

Plus, you don't need to bother with buffer sizes and proper deallocation anymore.

Comments

0

I believe even your 2nd example is also invalid

char m1[];
char m2[] = "sth"; 

m1 is not having any valid piece of memory to store the copied data. And, I believe you should have the array dimension in your declaration (you are not declaring a method param here)

Normally you should have something like

char m1[10];
char m2[] = "sth"; 
strcpy(m1, m2);

Go back to the question. Many people said you should allocate memory in order to use char*. It is not wrong, but more accurately, you should have the pointer pointing to valid piece of memory.

Allocating memory is one way, but you can also do something like this:

char outdata[100];
char* m1 = &(outdata[10]);
char* m2 = "foo";
strcpy(m1, m2);

no explicit allocation here, and still a valid example.

I believe OP is still not understanding what is an array and what is a pointer. Get some extra reading and thinking on that.

2 Comments

I'd like to know why I am given a downvote as I believe what I said is all valid
Not only valid but useful, too, I think. +1
-2

First of all, before you perform the copy you must assure that the destination pointer have enough memory to keep the copy, if you don't you'll get runtime errors. So you need this:

char* m1;
char* m2 = "sth";
m1 = new char[strlen(m2)+1]; // <---- reserve memory for m1
strcpy(m1, m2);
// remember to delete[] m1

Another way to deal with character strings is to use the std::string class instead, if you do, the memory management will not bother you.

std::string m1("");
std::string m2("sth");
m1 = m2; // no strcopy needed, no memory management needed

Finally, if for some reason you must deal with pointers, take care of the new/delete pair and remenber that the memory reserved with new[] must be deleted wit delete[].

And and additional advice: instead of memcpy i preffer the use of std::copy:

char* m1;
char* m2 = "sth";
m1 = new char[strlen(m2)+1]; // <---- reserve memory for m1
std::copy(std::begin(m2), std::end(m2), std::begin(m1));
// remember to delete[] m1

Because it works both for the char * and the std::string version if you use std::begin and std::end functions:

std::string m1("");
std::string m2("sth");
std::copy(std::begin(m2), std::end(m2), std::begin(m1));

Edit: It works as long the m2 are statically reserved so the length can be deduced at compile time.

7 Comments

m1 = new char[strlen(m2)]; // <---- reserve memory for m1 you forgot +1. strlen returns length of string without null terminator.
std::begin and std::end work with arrays but they don't work with pointers.
std::begin and std::end works both with arrays and pointers ;)
@PaperBirdMaster Erm, no, they don't. You may want to read the documentation you linked to.
@PaperBirdMaster None of them are pointers. You may want to read this answer: stackoverflow.com/a/4810668/46642
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.