views:

756

answers:

8

Basic question.

char new_str[]="";

char * newstr;

If I have to concatenate some data into it or use string functions like strcat/substr/strcpy, what's the difference between the two?

I understand I have to allocate memory to the char * approach (Line #2). I'm not really sure how though.

And const char * and string literals are the same?

I need to know more on this. Can someone point to some nice exhaustive content/material?

+1  A: 

Please go through this article below:

Also see in case of array of char like in your case, char new_str[] then the new_str will always point to the base of the array. The pointer in itself can't be incremented. Yes you can use subscripts to access the next char in array eg: new_str[3];

But in case of pointer to char, the pointer can be incremented new_str++ to fetch you the next character in the array.

Also I would suggest this article for more clarity.

Justin
+2  A: 

The difference is that one is a pointer, the other is an array. You can, for instance, sizeof() array. You may be interested in peeking here

Michael Krelin - hacker
+1  A: 

The type of the first is char[1], the second is char *. Different types.

Allocate memory for the latter with malloc in C, or new in C++.

char foo[] = "Bar";  // Allocates 4 bytes and fills them with
                     // 'B', 'a', 'r', '\0'.

The size here is implied from the initializer string.

The contents of foo are mutable. You can change foo[i] for example where i = 0..3.

OTOH if you do:

char *foo = "Bar";

The compiler now allocates a static string "Bar" in readonly memory and cannot be modified.

foo[i] = 'X';  // is now undefined.
Alex
Hmm. Nah. foo is not mutable. You cannot change foo. You can change the elements of foo, yes, but you cannot change foo to bar, if bar is also a char array, for example.
Johann Gerell
Fair enough, Mr Nitpicker.
Alex
A: 

If you're in c++ why not use std::string for all your string needs? Especially anything dealing with concatenation. This will save you from a lot of problems.

jilles de wit
A: 

If you're using C++ as your tags indicate, you really should be using the C++ strings, not the C char arrays.

The string type makes manipulating strings a lot easier.

If you're stuck with char arrays for some reason, the line:

char new_str[] = "";

allocates 1 byte of space and puts a null terminator character into it. It's subtly different from:

char *new_str = "";

since that may give you a reference to non-writable memory. The statement:

char *new_str;

on its own gives you a pointer but nothing that it points to. It can also have a random value if it's local to a function.

What people tend to do (in C rather than C++) is to do something like:

char *new_str = malloc (100); // (remember that this has to be freed) or
char new_str[100];

to get enough space.

If you use the str... functions, you're basically responsible for ensuring that you have enough space in the char array, lest you get all sorts of weird and wonderful practice at debugging code. If you use real C++ strings, a lot of the grunt work is done for you.

paxdiablo
+1  A: 

This is a character array:

char  buf [1000];

So, for example, this makes no sense:

buf = &some_other_buf;

This is because buf, though it has characteristics of type pointer, it is already pointing to the only place that makes sense for it.

char *ptr;

On the other hand, ptr is only a pointer, and may point somewhere. Most often, it's something like this:

ptr = buf;              // #1:  point to the beginning of buf, same as &buf[0]

or maybe this:

ptr = malloc (1000);    // #2:  allocate heap and point to it

or:

ptr = "abcdefghijklmn"; // #3:  string constant

For all of these, *ptr can be written to—except the third case where some compiling environment define string constants to be unwritable.

*ptr++ = 'h';          // writes into #1: buf[0], #2: first byte of heap, or
                       //             #3 overwrites "a"
strcpy (ptr, "ello");  // finishes writing hello and adds a NUL
wallyk
+1  A: 

The excellent source to clear up the confusion is Peter Van der Linden, Expert C Programming, Deep C secrets - that arrays and pointers are not the same is how they are addressed in memory.

With an array,

char new_str[];
the compiler has given the new_str a memory address that is known at both compilation and runtime, e.g. 0x1234, hence the indexing of the new_str is simple by using []. For example new_str[4], at runtime, the code picks the address of where new_str resides in, e.g. 0x1234 (that is the address in physical memory). by adding the index specifier [4] to it, 0x1234 + 0x4, the value can then be retrieved.

Whereas, with a pointer, the compiler gives the symbol

char *newstr
an address e.g. 0x9876, but at runtime, that address used, is an indirect addressing scheme. Supposing that newstr was malloc'd
newstr = malloc(10);
, what is happening is that, everytime a reference in the code is made to use newstr, since the address of newstr is known by the compiler i.e. 0x9876, but what is newstr pointing to is variable. At runtime, the code fetches data from physical memory 0x9876 (i.e. newstr), but at that address is, another memory address (since we malloc'd it), e.g 0x8765 it is here, the code fetches the data from that memory address that malloc assigned to newstr, i.e. 0x8765.

The char new_str[] and char *newstr are used interchangeably, since an zeroth element index of the array decays into a pointer and that explains why you could newstr[5] or *(newstr + 5) Notice how the pointer expression is used even though we have declared char *newstr, hence

*(new_str + 1) = *newstr;
OR
*(new_str + 1) = newstr[1];

In summary, the real difference between the two is how they are accessed in memory.

Get the book and read it and live it and breathe it. Its a brilliant book! :)

Hope this helps, best regards, Tom.

tommieb75
As a side note: C is noted to have commutative expressions, for example 4 + 3 is same as 3 + 4. This is true in pointers also,*(new_str + 1) is same as *(1 + new_str) which incidentally is1[new_str]. That was a joke and is referenced elsewhere on the net, probably to throw someone off. IT is rarely used in production, still have yet to see it somewhere!
tommieb75
A: 
char new_str[]="abcd";  

This specifies an array of characters (a string) of size 4 bytes (one byte for each character). So it stores the string 'abcd' in memory and we can access this string using the variable new_str.

char *new_str="abcd";  

This specifies a string 'abcd' is stored somewhere in the memory and the pointer new_str points to the first character of that string.

Mohit