|
|
arnuld wrote:
>> On Tue, 29 Apr 2008 18:34:16 -0700, Barry Schwarz wrote:
>
>>> On Tue, 29 Apr 2008 15:47:30 +0500, arnuld <NoSpam@xxxxxxxxxx>
>>> wrote:
>
>>> char *buffer = 0;
>>> char *buffer2 = NULL;
>>>
>>> printf("%s\n%s\n", buffer, buffer2);
>
>> Obviously you wanted to do something else rather than invoke
>> undefined
>> behavior here. Did you mean to use %p instead of %s? If so, it
>> would be a good to acquire the habit of casting the pointers to void*
>> (even though a char* would work without the cast).
>
> I really meant %s because I am providing printf an array, whether
> empty or full and you do see that its prints without any problem:
No. That's GNU C specific behaviour. You are confused between
initialising a pointer and later assigning to it. This
char *buf = 0;
is a declaration with an initialisation. It declares buf to a char * and
sets it to 0, which in a pointer context is automatically converted to
a null pointer value. buf is, after this initialisation, a null
pointer, something that is never legal to deference. The %s format
specifier needs a valid pointer pointing to a string, or a single null
character. The behaviour is undefined if a null pointer is passed to
it. It so happens that the GNU C compiler prints (null), but some other
compiler could merely segfault or do something even worse.
This series of statements
char *buf = 0;
buf = "";
declare buf as a char * and first set it to NULL. Then the second
statement sets buf to point to the start of an empty string, which is
simply a single null character. It is equivalent to this code:
char nullc = '\0'
char *buf = 0;
buf = &nullc;
with the caveat that the storage pointed to by the example above is
modifiable while the one preceding it is not. That's because string
literals are not, (or should not be), modifiable in C. Another
functionally equivalent code is:
char *buf = NULL;
buf = malloc(1 * sizeof *buf);
/* check malloc return */
*buf = 0;
So, in summary assigning a zero value to a pointer in an initialisation
is very different from assigning to it after deferencing it.
Can you understand the difference between these?
1. char *buf = 0;
2. char *buf;
buf = NULL;
3. char *buf;
char c = '\0';
buf = &c;
4. char *buf = NULL;
buf = "";
|
|