Click here to Skip to main content
15,881,559 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello,
This is my problem to need you to help me: When I declare:
char *str;

then str is sure a pointer, if I declare the following:
char str[16];

At the moment str is still a pointer? Or a variable? Plz help me. Thank for advances.
Posted
Updated 19-Jan-11 17:59pm
v2

char *str; declares a pointer. this pointer has no value, but you can change that by assigning it to another variable. This notation is usually used for dynamic strings allocated on the stack or keeping track of the current position in another string when parsing it.
the pointer value (4 bytes (8 on a 64bit platform)) is stored in the stack, while the memory referenced may be stored in the heap (new, malloc, ...)

char str[16];
allocates space on the stack (16 * sizeof(char) = 16 bytes) (in the same area where function calls and variables are stored)
This is also a pointer as far as the compiler is concerned, but this points to the first character in the string. Once compiled, there is no pointer value stored for it.

This makes another reference to the same string as the one on the stack. Changing 1 string will change both strings.
This is usually used for itterating through the characters of the string to find 1 that we are interested in, say a space char.
char strStack[12] = "hello world"; //allocate 12 chars on the stack
char *strStackPtr = strStack;


This allocates a new string to copy the contents of an existing one. Because we dont know the length of the other string (just pretend we dont) we need to allocate it dynamically so that we can modify 1 string without affecting the other
char strStack[12] = "hello world"; //allocate 12 chars on the stack
size_t nlen = strlen(strStack);
char *strHeap = new char[nlen];
strcpy(strHeap, strStack);
//do something with strHeap
delete []strHeap; //anything allocated on the heap must be free'd


There is limited space on the stack, so any long strings should be allocated on the heap with new or malloc. period. For small strings, you are safe (and often better to use the stack). It is much much quicker (and easier) to allocate a string on the stack, and it frees itself when it goes out of scope.

For strings that are hard coded and never going to change, you are best to just use
char *strSeg = "hello world";

This will allocate the string in the .exe file, and strSeg is a pointer to the location of the string in the .exe loaded into memory
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 20-Jan-11 0:42am    
Hm. Impressive level of detail (my 5). If you continue in such tempo, you're going to write a whole book :-)
Andrew Brock 20-Jan-11 0:52am    
Great, something to add to my CV for when I finish uni
Sergey Alexandrovich Kryukov 20-Jan-11 1:04am    
"Finish university" instead of "graduate from the university" is a well-known Russian mistake, even described in Wikipedia in the article about "Runglish", but you're from Australia...
Andrew Brock 20-Jan-11 1:15am    
Lol. In Australia we don't talk much about graduation, it is just something that happens then forgotten really. So I really just finish uni, just like I finished school... or did I graduate that too?
Sergey Alexandrovich Kryukov 20-Jan-11 1:21am    
Wow, I talked with Australians, but the biggest difference is pronunciation. I never heard of such a distinct grammar/usage difference as that -- quite far from both British and American English. Interesting to know.
char str[16];


isn't a pointer, it's an array of 16 characters. A array is a block of contiguous things in memory, a pointer is a variable that contains the address of something else.

Where you might be getting confused is that the name of an array is synonymous with the address of the first element of the array. So you can use the name of an array to initialise or assign to pointers.

So if you have a pointer you can use array style indexing on it, but if you have an array name you CAN'T do pointer style assignment on it. If you do something like:

char str[16];
char *p = str;


str and p refer to the same location in memory. You can then do something like:

p++;


and p will now point to the memory location of str[ 1 ]. However if you try:

str++;


the compiler will tell you take a walk as you can't modify the value str represents, it's a constant (it's an rvalue in standard speak if you ever try reading it, at least in C90, not sure about C99).

So the differences between array names and pointers are:

- pointers contain addresses
- array names are addresses
- doing a sizeof array_name gives you the number of bytes in the array
- doing a sizeof a pointer returns the number of bytes it takes to hold an address on your system

Now there's another source of confusion. When you pass an array to a function the compiler takes the address of the first element in the array and converts it to a pointer. So when you see a function prototype like:

void test( char b[ 20 ] );

you can read it like:

void test( char *b );

and if you do a sizeof on b within the function it'll come back as 4 or 8 (perhaps 2 on very old or embedded systems) depending on you compiler.

So we can add to the rules a bit:

- pointers contain addresses
- array names are addresses
- doing a sizeof array_name gives you the number of bytes in the array
- doing a sizeof a pointer returns the number of bytes it takes to hold an address on your system
- read all array names passed to functions as pointers within the scope of that function

Cheers,

Ash
 
Share this answer
 
Comments
Aescleal 20-Jan-11 10:55am    
To the person that marked me down - would you care to point out where I was wrong or what I could do to make the answer better?
Sergey Alexandrovich Kryukov 20-Jan-11 11:49am    
Some idiot came in and down-voted. Funny.
Avi Berger 20-Jan-11 11:14am    
My 5. At this time this is the only clear and fully correct answer. The OP's basic issue is the distinction between arrays and pointers. Even though "there is a strong relationship between pointers and arrays" (K & R) arrays are NOT pointers. The other answers are, at best, misleading on this point.
Espen Harlinn 20-Jan-11 14:51pm    
5+ Accurate and instructive answer
T2102 20-Jan-11 21:36pm    
Decent answer. Not all arrays (e.g. dynamic) are guaranteed to have contiguous memory even if the associated class has no pointers. I also would recommend using prefix operator instead of postfix operators when possible as it is more efficient.
The question if not correct: a pointer or not a pointer -- still a variable, or a function parameter. A str is a pointer in both cases.

The difference between your first and last line: if first line, the pointer is not yet initialized: on what character is points? In second line, a memory is allocated for 16 characters. If this is a local declaration, it is allocated on local stack when a function is executed, if not -- in the process static memory. The pointer is already initialized and point to the first character of the array of 16.

[EDIT]
Well, due to harsh arguments on this page, I admit I need to elaborate on the topic "array vs pointer".

Of course I understand that array and pointer are not exactly the same. In the above paragraph I described the difference in memory layout: with array, memory is always taken during initialization (stack or static). There is more to it. Consider the sample:

MIDL
char arr[16];
	
//will not compile: unknown size:
//char arr2[];
	
for(int index = 0; index < 16; index++)
   arr[index] = index + (int)'0';char* ptr;
ptr = arr;
ptr = &arr[0]; //same thing as before
char third = ptr[3]; //returns '3'
ptr[3] = '?'; //mutable

//makes no sense, compiler does not
//perform static check but it could
//can cause corruption during run-time:
ptr[9000] = '!';
	
//will not compile: "arr is a constant pointer",
//can be initialized, not assigned:
//arr = ptr;


So, during run-time arr behaves as a constant pointer, but the memory area it points to is mutable (pointer arr is constant, character arr[3] is not). There is not direct way to modify err as a pointer: it won't compile (last line of the sample).

During design time, there are more essential differences. In particular, array length is statically known, etc.
 
Share this answer
 
v3
Comments
Nish Nishant 20-Jan-11 9:36am    
Voted 5, proposed as answer.
Aescleal 20-Jan-11 11:01am    
Sorry, I really don't understand your answer - I'm hoping it's a language thing. You seem to be saying that both the declarations are pointers when they're not. The second one isn't a pointer at all, it's an array. There are loads of differences between the two that trip up beginning programmers who expect arrays and pointers to be the same after seeing such sweeping generalisations.
Sergey Alexandrovich Kryukov 20-Jan-11 11:45am    
This is a pointer. Period. Read elementary textbook before making any statements.
Yes, this is an array, so what? You need to understand the nature of both.
Is this your vote of "1". If so, this is too funny.
Avi Berger 20-Jan-11 12:08pm    
Actually, that's my vote of 1 and this comment of yours tells me it was valid. Read Aescleal's answer, his is accurate. You are right that you need to understand the nature of arrays and pointers. You are right that in "char str[16];" str is an array. Arrays are not pointers, so in this case str is most definitely not a pointer. Perhaps I should have added a comment as a correction rather than voting. I'll be happy to change my vote if you correct your answer. Now I'm out of time and have to run.
Sergey Alexandrovich Kryukov 20-Jan-11 12:14pm    
Fair enough. Thank you.
Your first example creates a pointer str (with unknown value).
Your second example creates an array of 16 chars, and sets the value of str to the address of (the first char in) the array.
In both cases, str works as a pointer; in the second case it is actually pointing to something.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900