strcpy() question

Hallo,
some things seem easy but they aren't so.
In C++ an array is equivalent to a pointer to the first element of the array. But if I use the strcpy() function in the following way it doesn't work:

1
2
3
4
char *cp1 = "kkkkkkkkkkkkk";
char *cp2 = "jjjjjj";
strcpy(cp1, cp2);	// runtime error!
cout << cp1 << endl;


What is the problem?
Thank you.

an array is equivalent to a pointer to the first element of the array.


"An array" is a block of memory consisting of repeated objects of the same type.
"A pointer to the first element of an array" is a pointer, whose value is the address of the first element of an array.
As you can see from the description, they're not equivalent and thinking of them as the same thing will lead you astray.


What happens if you try this?

1
2
char cp1[] = "kkkkkkkkkkkkk";
char cp2[] = "jjjjjj";


What have you created with this?

char *cp1;
Last edited on
closed account (N85iE3v7)
The format char* ptr = "string here"; is deprecated from C++. Use the option given by Moschops. In fact strings are arrays in C, but they are ended with a 0x00 character called string terminator.

1
2
// for example a string like
char cp2[] = "jjjjjj";


Will generate :
'j' <--- Cp2 points to here
'j'
'j'
'j'
'j'
0x00

The strcpy function will copy the second string to the first string by indexing this copy using the pointer to the start of the array . Cp2 and Cp1 are both pointers to the first item of the array.
You can see that both have different sizes and strcpy will not be able to copy the block memories because of this.

Strcpy it self is not a recommended function as there is a safer one strncpy that asks for the size of the buffer that is copied.

You have 3 options:

1- declare cp2 as a large buffer
1
2
3
4
5
char _buffer_[10];
//initated it
memset(_buffer_,0,10);// already has a terminator
//copy the string
strncpy(_buffer_,cp2,strlen(cp2));

2- Declare buffer dynamically
1
2
3
4
5
6
char* _buffer_ = new char[strlen(cp2)+1];
strncpy(_buffer_,cp2,strlen(cp2));
_buffer_[strlen(cp2)+1] = 0x00;
// use _buffer here
// deallocate it
delete[] buffer;

3-There is a string class on c++ , actually std::string
to use it:
1
2
#include <string>
using namespace std;

Note that string does not have a 0x00 terminator ( the char strings are also called NULL terminated strings ) but has lots of facilities that you make your life easier. Sometimes, it is useful to use C Style strings, especially when you are dealing with ascii characters or binary files.

Last edited on
both have different sizes and strcpy will not be able to copy the block memories because of this.


do you mean that strcpy will considered Cp1 and Cp2 as memory and not by value?
closed account (N85iE3v7)
yes, check:

http://www.cplusplus.com/reference/clibrary/cstring/strcpy/

The prototype:

char * strcpy ( char * destination, const char * source );

btw: when using a Cpp compiler the actual include for this function is
#include <cstring>

Ok, now I understand (I think). What has led me astray is an example like this:

1
2
int ia[10];
int* ip = ia;


In this case the array ia is actually and automatically converted to a pointer to first element; however, vice versa is not true, so the two objects are not equivalent.
Thank you to everybody.

In this case the array ia is actually and automatically converted to a pointer to first element; however, vice versa is not true, so the two objects are not equivalent.

Nope, that example just take the value of "ia" which is a memory address of the first element of the memory block reserved for the array and assign that to the pointer "ip". "ia" is still an array, you can't do pointer arithmetic with it.
This is what passing an array into a function does, just basic assignment.
OK, I have tried other examples, based on your comments, and now it is clear.
Thank you.
closed account (N85iE3v7)
Actually you can treat ia as a pointer to the first item of the array and from there you can use pointer arithmetic like:
1
2
3
int ia[10];
// ... you do some code here so that ia gets initialized with values here
*(ia + 0 ) = 1;// the same as if you did ia[0] 



Check
http://www.cplusplus.com/doc/tutorial/pointers/

In the chapter about arrays we used brackets ([]) several times in order to specify the index of an element of the array to which we wanted to refer. Well, these bracket sign operators [] are also a dereference operator known as offset operator. They dereference the variable they follow just as * does, but they also add the number between brackets to the address being dereferenced. For example:

1
2
a[5] = 0; // a [offset of 5] = 0
*(a+5) = 0; // pointed by (a+5) = 0


These two expressions are equivalent and valid both if a is a pointer or if a is an array.



Last edited on
Topic archived. No new replies allowed.