Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

difference between char* and char[] with strcpy()

Tags:

c

string

char

I've been having trouble the past couple hours on a problem I though I understood. Here's my trouble:

void cut_str(char* entry, int offset) {
    strcpy(entry, entry + offset);
}

char  works[128] = "example1\0";
char* doesnt = "example2\0";

printf("output:\n");

cut_str(works, 2);
printf("%s\n", works);

cut_str(doesnt, 2);
printf("%s\n", doesnt);

// output:
// ample1
// Segmentation: fault

I feel like there's something important about char*/char[] that I'm not getting here.

like image 695
weadmonkey Avatar asked Jun 29 '12 01:06

weadmonkey


People also ask

What is the difference between char * and char array?

The main difference between them is that the first is an array and the other one is a pointer. The array owns its contents, which happen to be a copy of "Test" , while the pointer simply refers to the contents of the string (which in this case is immutable). Why is char* str commonly used when str denotes a string.

Is there any difference between char * and char []?

The fundamental difference is that in one char* you are assigning it to a pointer, which is a variable. In char[] you are assigning it to an array which is not a variable.

Can I use strcpy for char?

The strcpy() Function in C It copies string pointed to by source into the destination . This function accepts two arguments of type pointer to char or array of characters and returns a pointer to the first string i.e destination .

What is the difference between character array and a character pointer?

arr is a collection of characters stored at a contiguous memory location whereas ptr holds the address of the character. See the above image, arr which contains 12 elements and each element is on a contiguous memory location. On the other hand, ptr hold the address of the first character of strings literal.


2 Answers

The difference is in that doesnt points to memory that belongs to a string constant, and is therefore not writable.

When you do this

char  works[128] = "example1\0";

the compiler copies the content of a non-writable string into a writable array. \0 is not required, by the way.

When you do this, however,

char* doesnt = "example2\0";

the compiler leaves the pointer pointing to a non-writable memory region. Again, \0 will be inserted by compiler.

If you are using gcc, you can have it warn you about initializing writable char * with string literals. The option is -Wwrite-strings. You will get a warning that looks like this:

 warning: initialization discards qualifiers from pointer target type

The proper way to declare your doesnt pointer is as follows:

const char* doesnt = "example2\0";
like image 131
Sergey Kalinichenko Avatar answered Nov 15 '22 06:11

Sergey Kalinichenko


The types char[] and char * are quite similar, so you are right about that. The difference lies in what happens when objects of the types are initialized. Your object works, of type char[], has 128 bytes of variable storage allocated for it on the stack. Your object doesnt, of type char *, has no storage on the stack.

Where exactly the string of doesnt is stored is not specified by the C standard, but most likely it is stored in a nonmodifiable data segment loaded when your program is loaded for execution. This isn't variable storage. Thus the segfault when you try to vary it.

like image 33
thb Avatar answered Nov 15 '22 07:11

thb