C string declaration

c, string

Solution

char* str1="string";

This makes `str1` a pointer; it points to the first character of the string literal. You should define it as `const`, because you're not allowed to modify a string literal:

const char *str1 = "string";

...

char str2[7]="string";

This makes `str2` an array of `char` (not a pointer), and copies the contents of the string literal into it. There's no need to define it as `const`; the array itself is writable. You can also omit the size and let it be determined by the initializer:

char str2[] = "string";

Then `sizeof str2 == 7` (6 bytes for `"string"` plus 1 for the terminating `'\0'`).

This:

char* str3=(char)malloc(sizeof(char)*7);

is written incorrectly, and it shouldn't even compile; at the very least, you should have gotten a warning from your compiler. You're casting the result of `malloc()` to type `char`. You should be converting it to `char*`:

char *str3 = (char*)malloc(sizeof(char) * 7);

But the cast is unnecessary, and can mask errors in some cases; see question 7.7 and following in the comp.lang.c FAQ:

char *str3 = malloc(sizeof(char) * 7);

But `sizeof(char)` is 1 by definition, so you can just write:

char *str3 = malloc(7);

`malloc()` allocates memory, but it doesn't initialize it, so if you try to print the string that `str3` points to, you'll get garbage -- or even a run-time crash if the allocated space doesn't happen to contain a terminating null character `'\0'`. You can initialize it with `strcpy()`, for example:

char *str3 = malloc(7);
if (str3 == NULL) {
    fprintf(stderr, "malloc failed\n");
    exit(EXIT_FAILURE);
}
strcpy(str3, "string");

You have to be very careful that the data you're copying is no bigger than the allocated space. (No, `strncpy() is not the answer to this problem.)

`void main()` is incorrect; it should be `int main(void)`. If your textbook told you to use `void main()` find a better textbook; its author doesn't know C very well.

And you need appropriate `#include` directives for any library functions you're using: `<stdio.h>` for `printf()`, `<stdlib.h>` for `exit()` and `malloc()`, and `<string.h>` for `strcpy()`. The documentation for each function should tell you which header to include.

I know this is a lot to absorb; don't expect to understand it all right away.

I mentioned the comp.lang.c FAQ; it's an excellent resource, particularly section 6, which discusses arrays and pointers and the often confusing relationship between them.

As for your question 3, how to return a string from a C function, that turns out to be surprisingly complicated because of the way C does memory allocation (basically it leaves to to manage it yourself). You can't safely return a pointer to a local variable, because the variable ceases to exist when the function returns, leaving the caller with a dangling pointer, so returning your `str2` is dangerous. Returning a string literal is ok, since that corresponds to an anonymous array that exists for the entire execution of your program. You can declare an array with `static` and return a pointer to it, or you can use `malloc()` (which is the most flexible approach, but it means the caller needs to `free()` the memory), or you can require the caller to pass in a pointer to a buffer into which your function will copy the result.

Some languages let you build a string value and simply return it from a function. C, as you're now discovering, is not one of those languages.

Problem

I am confused about some basics in C string declaration. I tried out the following code and I noticed some difference: ``` char* foo(){ char* str1="string"; char str2[7]="string"; char* str3=(char)malloc(sizeof(char)*7); return str1; /* OR: return str2; */ /* OR: return str3; */ } void main() { printf("%s",foo()); return 0; } ``` I made foo() return str1/2/3 one at a time, and tried to print the result in the main. str2 returned something weird, but str1 and str3 returned the actual "string". 1.Now, what's the difference between the three declarations? I think the reason why str2 didn't work is because it is declared as a local variable, is that correct? 2.Then what about str1? If the result remains after the foo() ended, wouldn't that cause memory leak? 3.I'm simply trying to write a function that returns a string in C, and use the value returned by that function for other stuff, which str declaration above should I use? Thanks in advance!

Original source