By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,445 Members | 1,329 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,445 IT Pros & Developers. It's quick & easy.

does a program work in all cases?

P: n/a
Hi,

This program works when tested with gdb ( see results 1) but when used
in a larger program where 12 becomes 1500 there exists a problem when
freeing the memory ( see results 2). Can anyone give any advise here?
--------------------------------------------------
#include <stdlib.h>
#include <stdio.h>

int main(void) {
int i;
char** arr;

arr = malloc(sizeof(char *)*12);
for (i = 0; i < 12; i++) {
arr[i] = malloc(sizeof(char)*5);
}
if (!(arr)) {
printf("Failed to allocate memory\n");
return 0;
}
for (i = 0; i < 12; i++) {
strcpy(arr[i],"Thi");
printf("Arr[%d]\t%s\n",i, arr[i]);
}
for (i = 0; i < 12; i++) {
free(arr[i]);
}
free(arr);
return 1;
}
---------------------------------------------

Result 1:

% gdb a.out
GNU gdb 6.0-2mdk (Mandrake Linux)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and
you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for
details.
This GDB was configured as "i586-mandrake-linux-gnu"...Using host
libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) run
Starting program: a.out
Arr[0] Thi
Arr[1] Thi
Arr[2] Thi
Arr[3] Thi
Arr[4] Thi
Arr[5] Thi
Arr[6] Thi
Arr[7] Thi
Arr[8] Thi
Arr[9] Thi
Arr[10] Thi
Arr[11] Thi

Program exited with code 01.
(gdb)

Results 2:

free(): invalid pointer 0x40426814!
free(): invalid pointer 0x40442c74!
free(): invalid pointer 0x40426874!
free(): invalid pointer 0x40442c54!
free(): invalid pointer 0x404268d4!
free(): invalid pointer 0x40442cb4!

This problem eludes me. Any help is appreciated.

/S

Dec 17 '06 #1
Share this Question
Share on Google+
42 Replies


P: n/a
"Sheldon" <sh******@gmail.comwrites:
int i;
char** arr;
arr = malloc(sizeof(char *)*12);
for (i = 0; i < 12; i++) {
arr[i] = malloc(sizeof(char)*5);
}
if (!(arr)) {
printf("Failed to allocate memory\n");
return 0;
}

Probably not the cause of your problem,
but you should check for allocation failure of 'arr' immediately after you
attempt the allocation, and certainly before you access arr[i].

--
Chris.
Dec 17 '06 #2

P: n/a
On 2006-12-17, Sheldon <sh******@gmail.comwrote:
Hi,

This program works when tested with gdb ( see results 1) but when used
in a larger program where 12 becomes 1500 there exists a problem when
freeing the memory ( see results 2). Can anyone give any advise here?
Are you sure you changed all the "12"s to "1500"s?

I would expect the program to work OK, although I've made one or two
comments below you didn't ask for :)
--------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
Also need <string.hfor strcpy
>
int main(void) {
int i;
char** arr;

arr = malloc(sizeof(char *)*12);
for (i = 0; i < 12; i++) {
arr[i] = malloc(sizeof(char)*5);
You don't check these allocations...
}
if (!(arr)) {
printf("Failed to allocate memory\n");
....even though you do check this one, but only after using it, which is
a bit late.

You also should really go if (arr != NULL) because !NULL is not
necessarily true on all platforms.

And you could consider printing the error to stderr rather than stdout.
return 0;
Usually 0 is returned for success, not failure.
}
for (i = 0; i < 12; i++) {
strcpy(arr[i],"Thi");
printf("Arr[%d]\t%s\n",i, arr[i]);
}
for (i = 0; i < 12; i++) {
free(arr[i]);
}
free(arr);
return 1;
Usually 0 is returned for success, not failure.

And for portability, I think I've read here you should only return 0,
EXIT_SUCCESS or EXIT_FAILURE from main.
Dec 17 '06 #3

P: n/a

Chris McDonald skrev:
"Sheldon" <sh******@gmail.comwrites:
int i;
char** arr;
arr = malloc(sizeof(char *)*12);
for (i = 0; i < 12; i++) {
arr[i] = malloc(sizeof(char)*5);
}
if (!(arr)) {
printf("Failed to allocate memory\n");
return 0;
}


Probably not the cause of your problem,
but you should check for allocation failure of 'arr' immediately after you
attempt the allocation, and certainly before you access arr[i].

--
Chris.
I thought I did that with:
if (!(arr)) {
printf("Failed to allocate memory\n");
return 0;
}
Is this not the same as
if(arr==NULL) {
printf("Failed to allocate memory\n");
return 0;
}
?

/S

Dec 17 '06 #4

P: n/a

Ben C skrev:
On 2006-12-17, Sheldon <sh******@gmail.comwrote:
Hi,

This program works when tested with gdb ( see results 1) but when used
in a larger program where 12 becomes 1500 there exists a problem when
freeing the memory ( see results 2). Can anyone give any advise here?

Are you sure you changed all the "12"s to "1500"s?

I would expect the program to work OK, although I've made one or two
comments below you didn't ask for :)
--------------------------------------------------
#include <stdlib.h>
#include <stdio.h>

Also need <string.hfor strcpy

int main(void) {
int i;
char** arr;

arr = malloc(sizeof(char *)*12);
for (i = 0; i < 12; i++) {
arr[i] = malloc(sizeof(char)*5);

You don't check these allocations...
}
if (!(arr)) {
printf("Failed to allocate memory\n");

...even though you do check this one, but only after using it, which is
a bit late.

You also should really go if (arr != NULL) because !NULL is not
necessarily true on all platforms.

And you could consider printing the error to stderr rather than stdout.
return 0;

Usually 0 is returned for success, not failure.
}
for (i = 0; i < 12; i++) {
strcpy(arr[i],"Thi");
printf("Arr[%d]\t%s\n",i, arr[i]);
}
for (i = 0; i < 12; i++) {
free(arr[i]);
}
free(arr);
return 1;

Usually 0 is returned for success, not failure.

And for portability, I think I've read here you should only return 0,
EXIT_SUCCESS or EXIT_FAILURE from main.
Ok, thanks. I will make the necessary changes and yes 12 was changed to
1500. I am sure of it.

/S

Dec 17 '06 #5

P: n/a
"Sheldon" <sh******@gmail.comwrites:

>Chris McDonald skrev:
>"Sheldon" <sh******@gmail.comwrites:
int i;
char** arr;
arr = malloc(sizeof(char *)*12);
for (i = 0; i < 12; i++) {
arr[i] = malloc(sizeof(char)*5);
}
if (!(arr)) {
printf("Failed to allocate memory\n");
return 0;
}


Probably not the cause of your problem,
but you should check for allocation failure of 'arr' immediately after you
attempt the allocation, and certainly before you access arr[i].

--
Chris.
>I thought I did that with:
if (!(arr)) {
printf("Failed to allocate memory\n");
return 0;
}
Is this not the same as
if(arr==NULL) {
printf("Failed to allocate memory\n");
return 0;
}
You access/write arr[i] *before* you check if the allocation of arr
was a success.

--
Chris.
Dec 17 '06 #6

P: n/a
Ben C <sp******@spam.eggswrites:
On 2006-12-17, Sheldon <sh******@gmail.comwrote:
[...]
> if (!(arr)) {
printf("Failed to allocate memory\n");
[...]
You also should really go if (arr != NULL) because !NULL is not
necessarily true on all platforms.
Yes, it is. The expressions (arr != NULL) and (!arr) are exactly
equivalent, assuming arr is a pointer.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 17 '06 #7

P: n/a

Chris McDonald skrev:
"Sheldon" <sh******@gmail.comwrites:

Chris McDonald skrev:
"Sheldon" <sh******@gmail.comwrites:

int i;
char** arr;

arr = malloc(sizeof(char *)*12);
for (i = 0; i < 12; i++) {
arr[i] = malloc(sizeof(char)*5);
}
if (!(arr)) {
printf("Failed to allocate memory\n");
return 0;
}
Probably not the cause of your problem,
but you should check for allocation failure of 'arr' immediately after you
attempt the allocation, and certainly before you access arr[i].

--
Chris.
I thought I did that with:
if (!(arr)) {
printf("Failed to allocate memory\n");
return 0;
}
Is this not the same as
if(arr==NULL) {
printf("Failed to allocate memory\n");
return 0;
}

You access/write arr[i] *before* you check if the allocation of arr
was a success.

--
Chris.
Ok, I see now

Will make the change.
/S

Dec 17 '06 #8

P: n/a
Ben C wrote:
On 2006-12-17, Sheldon <sh******@gmail.comwrote:
}
if (!(arr)) {
printf("Failed to allocate memory\n");

...even though you do check this one, but only after using it, which is
a bit late.

You also should really go if (arr != NULL) because !NULL is not
necessarily true on all platforms.
NULL is 0 or (void *) 0 and paragraph 5 of 6.5.3.3
of N1124 says that applying the ! operator to a zero
value gives 1. So !NULL will be true on all conforming
platforms.

Dec 17 '06 #9

P: n/a
In article <11**********************@79g2000cws.googlegroups. com>,
Spiros Bousbouras <sp****@gmail.comwrote:
>Ben C wrote:
>On 2006-12-17, Sheldon <sh******@gmail.comwrote:
}
if (!(arr)) {
printf("Failed to allocate memory\n");

...even though you do check this one, but only after using it, which is
a bit late.

You also should really go if (arr != NULL) because !NULL is not
necessarily true on all platforms.
>NULL is 0 or (void *) 0 and paragraph 5 of 6.5.3.3
of N1124 says that applying the ! operator to a zero
value gives 1. So !NULL will be true on all conforming
platforms.
No, NULL is *not* necessarily 0 or (void *)0 : it can have
any internal representation the compiler desires. What the
standard promises is that it will *compare* equal to 0.
Meanwhile !p is just shorthand for p!=0 and as NULL must compare
equal to 0, p!=0 must be false if p is NULL.

It's the same end result, but the internal details are
different than you are implying.

--
There are some ideas so wrong that only a very intelligent person
could believe in them. -- George Orwell
Dec 18 '06 #10

P: n/a
Sheldon wrote:
>
Hi,

This program works when tested with gdb ( see results 1) but when used
in a larger program where 12 becomes 1500 there exists a problem when
freeing the memory ( see results 2). Can anyone give any advise here?
--------------------------------------------------
#include <stdlib.h>
#include <stdio.h>

int main(void) {
int i;
char** arr;

arr = malloc(sizeof(char *)*12);
for (i = 0; i < 12; i++) {
arr[i] = malloc(sizeof(char)*5);
}
if (!(arr)) {
printf("Failed to allocate memory\n");
return 0;
}
for (i = 0; i < 12; i++) {
strcpy(arr[i],"Thi");
printf("Arr[%d]\t%s\n",i, arr[i]);
}
for (i = 0; i < 12; i++) {
free(arr[i]);
}
free(arr);
return 1;
}
/* BEGIN new.c */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define NUMBER 12
#define STRING "Thi"

int main(void)
{
int i;
char** arr;

arr = malloc(NUMBER * sizeof *arr);
if (arr == NULL) {
puts("Failed to allocate memory");
exit(EXIT_FAILURE);
}
for (i = 0; i < NUMBER; i++) {
arr[i] = malloc(sizeof STRING);
if (arr[i] == NULL) {
while (i-- != 0) {
free(arr[i]);
}
free(arr);
arr = NULL;
}
}
if (arr == NULL) {
puts("Failed to allocate memory");
exit(EXIT_FAILURE);
}
for (i = 0; i < NUMBER; i++) {
strcpy(arr[i], STRING);
printf("Arr[%d]\t%s\n", i, arr[i]);
}
for (i = 0; i < NUMBER; i++) {
free(arr[i]);
}
free(arr);
return 0;
}

/* END new.c */

--
pete
Dec 18 '06 #11

P: n/a
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
In article <11**********************@79g2000cws.googlegroups. com>,
Spiros Bousbouras <sp****@gmail.comwrote:
>>Ben C wrote:
[..snip..]
>>NULL is 0 or (void *) 0 and paragraph 5 of 6.5.3.3
of N1124 says that applying the ! operator to a zero
value gives 1. So !NULL will be true on all conforming
platforms.

No, NULL is *not* necessarily 0 or (void *)0 : it can have
any internal representation the compiler desires. What the
standard promises is that it will *compare* equal to 0.
Meanwhile !p is just shorthand for p!=0 and as NULL must compare
equal to 0, p!=0 must be false if p is NULL.
I doubt that `!p' is a shorthand for `p != 0' (atleast according to my
reading of the standards text)
>
It's the same end result, but the internal details are
different than you are implying.
For quite some time i wanted to know if applying unary operator `!' to
a value of a pointer type will behave like implicit comparison with a
null pointer constant. After studying n869 i am not convinced, perhaps
someone would be kind enough to clarify the issue?

<quote>
6.2.5 Types

....

[#21] Integer and floating types are collectively called
arithmetic types. Arithmetic types and pointer types are
collectively called scalar types. Array and structure types
are collectively called aggregate types.34)
</quote>

<quote>
6.5.3.3 Unary arithmetic operators

....

Constraints

[#1] The operand of the unary + or - operator shall have
arithmetic type; of the ~ operator, integer type; of the !
operator, scalar type.

....

[#5] The result of the logical negation operator ! is 0 if
the value of its operand compares unequal to 0, 1 if the
value of its operand compares equal to 0. The result has
type int. The expression !E is equivalent to (0==E).
</quote>

Now, one has a freedom to apply `!' to a value which has a pointer
type (since 6.5.2 says that pointer types are included into scalar
types).

So far so good.

<quote>
6.5.9 Equality operators

....

Constraints

[#2] One of the following shall hold:

....

-- one operand is a pointer and the other is a null
pointer constant.

....

[#5] Otherwise, at least one operand is a pointer. If one
operand is a null pointer constant, it is converted to the
type of the other operand. If one operand is a pointer to
an object or incomplete type and the other is a pointer to a
qualified or unqualified version of void, the former is
converted to the type of the latter.

[#6] Two pointers compare equal if and only if both are null |
pointers, both are pointers to the same object (including a
pointer to an object and a subobject at its beginning) or
function, both are pointers to one past the last element of
the same array object, or one is a pointer to one past the
end of one array object and the other is a pointer to the
start of a different array object that happens to
immediately follow the first array object in the address
space.82)

</quote>

Now taking into account:

<quote>
6.3.2.3 Pointers

....

[#3] An integer constant expression with the value 0, or
such an expression cast to type void *, is called a null
pointer constant.48) If a null pointer constant is |
converted to a pointer type, the resulting pointer, called a
null pointer, is guaranteed to compare unequal to a pointer
to any object or function.
</quote>

6.5.3.3(5) says that `!E' is equivalent to (0==E) but 6.3.2.3 seems to
suggest that uncasted 0 is not a null pointer constant. And this
situation does not fall under 6.5.9(5)

If my memory serves me the `null pointer constat' issue was hotly
debated recently (perhaps even on comp.lang.c), but i don't remember
the outcome, and in any case just want to know whether i should
continue using `!' on pointers. Perhaps this was covered in the later
drafts, or other parts of the standard.

--
vale
Dec 18 '06 #12

P: n/a
malc wrote:
[#3] An integer constant expression with the value 0, or
such an expression cast to type void *, is called a null
pointer constant.
>6.3.2.3 seems to
suggest that uncasted 0 is not a null pointer constant.
No, it doesn't suggest that at all.

--
pete
Dec 18 '06 #13

P: n/a
pete <pf*****@mindspring.comwrites:
malc wrote:
> [#3] An integer constant expression with the value 0, or
such an expression cast to type void *, is called a null
pointer constant.
>>6.3.2.3 seems to
suggest that uncasted 0 is not a null pointer constant.

No, it doesn't suggest that at all.
Why? The condition is clearly spelled out, the expression must be
cast to type void * to be called null pointer constant.

--
vale
Dec 18 '06 #14

P: n/a
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
In article <11**********************@79g2000cws.googlegroups. com>,
Spiros Bousbouras <sp****@gmail.comwrote:
>>Ben C wrote:
>>On 2006-12-17, Sheldon <sh******@gmail.comwrote:
}
if (!(arr)) {
printf("Failed to allocate memory\n");

...even though you do check this one, but only after using it, which is
a bit late.

You also should really go if (arr != NULL) because !NULL is not
necessarily true on all platforms.
>>NULL is 0 or (void *) 0 and paragraph 5 of 6.5.3.3
of N1124 says that applying the ! operator to a zero
value gives 1. So !NULL will be true on all conforming
platforms.

No, NULL is *not* necessarily 0 or (void *)0 : it can have
any internal representation the compiler desires. What the
standard promises is that it will *compare* equal to 0.
Meanwhile !p is just shorthand for p!=0 and as NULL must compare
equal to 0, p!=0 must be false if p is NULL.

It's the same end result, but the internal details are
different than you are implying.
NULL is a macro; in itself, it has no "internal representation". It
expands to a sequence of tokens; 0 and (void*)0, or rather ((void*)0)
are two of the most likely possibilities.

Most uses of the NULL macro will result in a null pointer value at run
time; applying the unary ! operator to this value will always yield 1.

The distinction between the NULL macro, null pointer constants, and
null pointer values is an important one.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 18 '06 #15

P: n/a
malc wrote:
>
pete <pf*****@mindspring.comwrites:
malc wrote:
[#3] An integer constant expression with the value 0, or
such an expression cast to type void *, is called a null
pointer constant.
>6.3.2.3 seems to
suggest that uncasted 0 is not a null pointer constant.
No, it doesn't suggest that at all.

Why? The condition is clearly spelled out, the expression must be
cast to type void * to be called null pointer constant.
"or" doesn't mean "and must be".

Can you find the word "or" in the quoted text?

--
pete
Dec 18 '06 #16

P: n/a
malc wrote:
>
.... snip ...
>
I doubt that `!p' is a shorthand for `p != 0' (atleast according
to my reading of the standards text)
Both are logical operators, and all logical operators return either
0 or 1.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 18 '06 #17

P: n/a
malc <ma**@pulsesoft.comwrites:
[...]
Now taking into account:

<quote>
6.3.2.3 Pointers

...

[#3] An integer constant expression with the value 0, or
such an expression cast to type void *, is called a null
pointer constant.48) If a null pointer constant is |
converted to a pointer type, the resulting pointer, called a
null pointer, is guaranteed to compare unequal to a pointer
to any object or function.
</quote>

6.5.3.3(5) says that `!E' is equivalent to (0==E) but 6.3.2.3 seems to
suggest that uncasted 0 is not a null pointer constant. And this
situation does not fall under 6.5.9(5)
Read 6.3.2.3 again:

An integer constant expression with the value 0, or such an
expression cast to type void *, is called a null pointer constant.

The integer constant 0, without a cast, most certainly is a null
pointer constant.
If my memory serves me the `null pointer constat' issue was hotly
debated recently (perhaps even on comp.lang.c), but i don't remember
the outcome, and in any case just want to know whether i should
continue using `!' on pointers. Perhaps this was covered in the later
drafts, or other parts of the standard.
There's a great deal of confusion about null pointer constants, but
there's really not much room for debate. I know of a couple of subtle
issues with respect to the standard's definition (see below), but
nothing that a typical programmer needs to worry about. Section 5 of
the comp.lang.c FAQ, <http://www.c-faq.com/>, explains null pointers,
null pointer constants, and the NULL macro quite well.

The subtle points (feel free to stop reading right now):

According to the language definition, at least as I interpret it, an
unadorned integer constant 0 is by definition a "null pointer
constant" even if it doesn't appear in a context that requires one.
For example, this:
int x = 0;
contains a null pointer constant, even though there's not a pointer
object or value in sight. This is a bit counterintuitive, but it's
really not a problem; just ignore the fact that it's a null pointer
constant unless you need it to be one.

The definition of a parenthesized expression says that it has certain
of the same properties as the unparenthesized expression, namely its
type, its value, whether it's an lvalue, whether it's a function
designator, and whether it's a void expression. Note that the list of
properties does *not* include whether it's a null pointer constant.
So, strictly speaking, (void*)0 is a null pointer constant, but
((void*)0) is not. But the standard requires definitions of
object-like macros in the standard library to be fully parenthesized
where necessary. So, by a strict reading of the standard, NULL cannot
expand to (void*)0 because it's not fully parenthesized (consider
sizeof NULL), but it can't expand to ((void*)0) because that's not a
null pointer constant. It's obvious, though, that a parenthesized
null pointer constant is *intended* to be a null pointer constant, and
many implementations just go ahead and define NULL as ((void*)0).
(One could argue, I suppose, that treating ((void*)0) as a null
pointer constant is an implementation-specific extension.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 18 '06 #18

P: n/a
pete <pf*****@mindspring.comwrites:
malc wrote:
>>
pete <pf*****@mindspring.comwrites:
malc wrote:

[#3] An integer constant expression with the value 0, or
such an expression cast to type void *, is called a null
pointer constant.

6.3.2.3 seems to
suggest that uncasted 0 is not a null pointer constant.

No, it doesn't suggest that at all.

Why? The condition is clearly spelled out, the expression must be
cast to type void * to be called null pointer constant.

"or" doesn't mean "and must be".

Can you find the word "or" in the quoted text?
Yes. `or' eluded me completely, thank you for pointing it out.

--
vale
Dec 18 '06 #19

P: n/a
pete wrote:
malc wrote:

> [#3] An integer constant expression with the value 0, or
such an expression cast to type void *, is called a null
pointer constant.


>>6.3.2.3 seems to
suggest that uncasted 0 is not a null pointer constant.


No, it doesn't suggest that at all.
Gentlemen, are you discussing CPLUSPLUS???
Because "zero equals NULL" as far as I know
only applies there.....
Dec 18 '06 #20

P: n/a
Sjouke Burry <bu*************@ppllaanneett.nnlllwrites:
pete wrote:
>malc wrote:
>> [#3] An integer constant expression with the value 0, or
such an expression cast to type void *, is called a null
pointer constant.
>>>6.3.2.3 seems to
suggest that uncasted 0 is not a null pointer constant.
No, it doesn't suggest that at all.
Gentlemen, are you discussing CPLUSPLUS???
Because "zero equals NULL" as far as I know
only applies there.....
No, we're discussing C. In C, an integer constant expression with the
value 0 is a null pointer constant. (This does not imply that a null
pointer has an all-bits-zero representation). See section 5 of the
comp.lang.c FAQ.

(C++ may or may not have different rules.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 18 '06 #21

P: n/a
CBFalconer wrote:
>
malc wrote:
... snip ...

I doubt that `!p' is a shorthand for `p != 0' (atleast according
to my reading of the standards text)

Both are logical operators, and all logical operators return either
0 or 1.
Yes, but ..., (!p) is equivalent to (p == 0).

Walter Roberson wrote, and you snipped:
"!p is just shorthand for p!=0",
which is what malc was disputing.

--
pete
Dec 18 '06 #22

P: n/a
Keith Thompson <ks***@mib.orgwrites:

[..snip..]
>situation does not fall under 6.5.9(5)

Read 6.3.2.3 again:

An integer constant expression with the value 0, or such an
expression cast to type void *, is called a null pointer constant.

The integer constant 0, without a cast, most certainly is a null
pointer constant.
Yes, i missed the `or' part hence the confusion.

[..snip..]
>
There's a great deal of confusion about null pointer constants, but
there's really not much room for debate. I know of a couple of subtle
issues with respect to the standard's definition (see below), but
nothing that a typical programmer needs to worry about. Section 5 of
the comp.lang.c FAQ, <http://www.c-faq.com/>, explains null pointers,
null pointer constants, and the NULL macro quite well.
Thank you for the pointer.
The subtle points (feel free to stop reading right now):

According to the language definition, at least as I interpret it, an
unadorned integer constant 0 is by definition a "null pointer
constant" even if it doesn't appear in a context that requires one.
For example, this:
int x = 0;
contains a null pointer constant, even though there's not a pointer
object or value in sight. This is a bit counterintuitive, but it's
really not a problem; just ignore the fact that it's a null pointer
constant unless you need it to be one.
Heh, this is part of the problem Herb Sutter and Bjarne Stroustrup are
trying to address in their nullptr proposal for C++. Sorry for OT.
The definition of a parenthesized expression says that it has certain
of the same properties as the unparenthesized expression, namely its
type, its value, whether it's an lvalue, whether it's a function
designator, and whether it's a void expression. Note that the list of
properties does *not* include whether it's a null pointer constant.
So, strictly speaking, (void*)0 is a null pointer constant, but
((void*)0) is not. But the standard requires definitions of
object-like macros in the standard library to be fully parenthesized
where necessary. So, by a strict reading of the standard, NULL cannot
expand to (void*)0 because it's not fully parenthesized (consider
sizeof NULL), but it can't expand to ((void*)0) because that's not a
null pointer constant. It's obvious, though, that a parenthesized
null pointer constant is *intended* to be a null pointer constant, and
many implementations just go ahead and define NULL as ((void*)0).
(One could argue, I suppose, that treating ((void*)0) as a null
pointer constant is an implementation-specific extension.)
If i understand you correctly you are implying that null pointer
constant has a type (and/or) value that is distinct from any other?
(otherwise standard is in the clear afaics)

In any case that was interesting, thank you.

--
vale
Dec 18 '06 #23

P: n/a
Sjouke Burry wrote:
>
pete wrote:
malc wrote:
[#3] An integer constant expression with the value 0, or
such an expression cast to type void *, is called a null
pointer constant.
Gentlemen, are you discussing CPLUSPLUS???
Because "zero equals NULL" as far as I know
only applies there.....
(0 == NULL) is always true in C.

What do you think malc is quoting above?

--
pete
Dec 18 '06 #24

P: n/a
pete <pf*****@mindspring.comwrites:
CBFalconer wrote:
>>
malc wrote:
>
... snip ...
>
I doubt that `!p' is a shorthand for `p != 0' (atleast according
to my reading of the standards text)

Both are logical operators, and all logical operators return either
0 or 1.

Yes, but ..., (!p) is equivalent to (p == 0).
Standard says that it is equivalent to (0==p), i'm not really sure if
== is commutative in all contexts it is allowed
Walter Roberson wrote, and you snipped:
"!p is just shorthand for p!=0",
which is what malc was disputing.
Indeed. Another question whether it's always true that:
x==y === !(x!=y)

--
vale
Dec 18 '06 #25

P: n/a
pete wrote:
CBFalconer wrote:
>malc wrote:
>>>
... snip ...
>>>
I doubt that `!p' is a shorthand for `p != 0' (atleast according
to my reading of the standards text)

Both are logical operators, and all logical operators return either
0 or 1.

Yes, but ..., (!p) is equivalent to (p == 0).

Walter Roberson wrote, and you snipped:
"!p is just shorthand for p!=0",
which is what malc was disputing.
A case of my failure to read with a suitably suspicious attitude
:-)

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Dec 18 '06 #26

P: n/a
Keith Thompson wrote:
Ben C <sp******@spam.eggswrites:
On 2006-12-17, Sheldon <sh******@gmail.comwrote:
[...]
if (!(arr)) {
printf("Failed to allocate memory\n");
[...]
You also should really go if (arr != NULL) because !NULL is not
necessarily true on all platforms.

Yes, it is. The expressions (arr != NULL)
and (!arr) are exactly equivalent, assuming arr is a pointer.
ITYM the expressions (arr == NULL) and (!arr) are equivalent...

--
Peter

Dec 18 '06 #27

P: n/a
malc <ma**@pulsesoft.comwrites:
[...]
If i understand you correctly you are implying that null pointer
constant has a type (and/or) value that is distinct from any other?
No, not at all.

A null pointer constant has whatever type it has as an expression.
It's either "[a]n integer constant expression with the value 0", which
has a type dependent on the form of the expression (0 is int, 0L is
long int, etc.), or "such an expression cast to type void*", which has
type void*.

A null pointer constant may be converted to a pointer type, either
explicitly or implicitly; the result of the conversion has that
pointer type.

Implicit conversions can make this tricky. For example:

double *p;
p = 0;

The expression 0, by itself, has type int. Since it's a null pointer
constant, it may be (and in this case is) implicitly converted to
double*; the result of the conversion is of type double*. The int
expression and the double* expression happen to look exactly alike:
the single token 0. (You can imagine an invisible conversion
operator, but the standard doesn't describe it in those terms.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 18 '06 #28

P: n/a
"Peter Nilsson" <ai***@acay.com.auwrites:
Keith Thompson wrote:
>Ben C <sp******@spam.eggswrites:
On 2006-12-17, Sheldon <sh******@gmail.comwrote:
[...]
> if (!(arr)) {
printf("Failed to allocate memory\n");
[...]
You also should really go if (arr != NULL) because !NULL is not
necessarily true on all platforms.

Yes, it is. The expressions (arr != NULL)
and (!arr) are exactly equivalent, assuming arr is a pointer.

ITYM the expressions (arr == NULL) and (!arr) are equivalent...
YTWIM. (Yes, that's what I meant.)

But hey, what's a logical inversion among friends?

To summarize: OOPS!

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 18 '06 #29

P: n/a
malc wrote:
>
pete <pf*****@mindspring.comwrites:
(!p) is equivalent to (p == 0).
Standard says that it is equivalent to (0==p), i'm not really sure if
== is commutative in all contexts it is allowed
Another question whether it's always true that:
x==y === !(x!=y)
Think about it.

--
pete
Dec 18 '06 #30

P: n/a
malc said:
pete <pf*****@mindspring.comwrites:
<snip>
>Yes, but ..., (!p) is equivalent to (p == 0).

Standard says that it is equivalent to (0==p), i'm not really sure if
== is commutative in all contexts it is allowed
It is.

<snip>
[...] Another question whether it's always true that:
x==y === !(x!=y)
It is. x!=y yields 0 if they are equivalent, but 1 if they are not. !0 is 1,
and !1 is 0. So !(x!=y) yields 1 if they are equivalent, but 0 if they are
not, just like x==y.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 18 '06 #31

P: n/a
2006-12-18 <m2************@pulsesoft.com>,
malc wrote:
pete <pf*****@mindspring.comwrites:
>malc wrote:
>> [#3] An integer constant expression with the value 0, or
such an expression cast to type void *, is called a null
pointer constant.
>>>6.3.2.3 seems to
suggest that uncasted 0 is not a null pointer constant.

No, it doesn't suggest that at all.

Why? The condition is clearly spelled out, the expression must be
cast to type void * to be called null pointer constant.
http://dictionary.reference.com/search?q=or
Dec 18 '06 #32

P: n/a
2006-12-18 <ln************@nuthaus.mib.org>,
Keith Thompson wrote:
Sjouke Burry <bu*************@ppllaanneett.nnlllwrites:
>pete wrote:
>>malc wrote:

[#3] An integer constant expression with the value 0, or
such an expression cast to type void *, is called a null
pointer constant.

6.3.2.3 seems to
suggest that uncasted 0 is not a null pointer constant.
No, it doesn't suggest that at all.
Gentlemen, are you discussing CPLUSPLUS???
Because "zero equals NULL" as far as I know
only applies there.....

No, we're discussing C. In C, an integer constant expression with the
value 0 is a null pointer constant. (This does not imply that a null
pointer has an all-bits-zero representation). See section 5 of the
comp.lang.c FAQ.

(C++ may or may not have different rules.)
OT: C++ misses entirely the point of having void * - I think, though,
that it doesn't actually forbid NULL expanding to ((void*)0) - a
compiler could special-case this to not be an error when assigned to
other pointers.
Dec 18 '06 #33

P: n/a
2006-12-18 <P8******************************@bt.com>,
Richard Heathfield wrote:
>[...] Another question whether it's always true that:
x==y === !(x!=y)

It is. x!=y yields 0 if they are equivalent, but 1 if they are not. !0 is 1,
and !1 is 0. So !(x!=y) yields 1 if they are equivalent, but 0 if they are
not, just like x==y.
What if x is not a number? Don't the comparison operators behave
strangely in those cases? I know that x >= y and x < y are then both
false at least.
Dec 18 '06 #34

P: n/a
pete <pf*****@mindspring.comwrites:
malc wrote:
>>
pete <pf*****@mindspring.comwrites:
>(!p) is equivalent to (p == 0).
>Standard says that it is equivalent to (0==p), i'm not really sure if
== is commutative in all contexts it is allowed
>Another question whether it's always true that:
x==y === !(x!=y)

Think about it.
I am well aware of De Morgan's laws. What i do not know if there might
be a case (covered by standard) where `==' is defined for given `x' and
`y' and `!=' not.

--
vale
Dec 18 '06 #35

P: n/a
Random832 said:
2006-12-18 <P8******************************@bt.com>,
Richard Heathfield wrote:
>>[...] Another question whether it's always true that:
x==y === !(x!=y)

It is. x!=y yields 0 if they are equivalent, but 1 if they are not. !0 is
1, and !1 is 0. So !(x!=y) yields 1 if they are equivalent, but 0 if they
are not, just like x==y.

What if x is not a number?
If it's not a number, it's a pointer. If it's a pointer, so is y.

If the pointers point to the same object, they will compare equal (whether
or not they have the same object representation).
Don't the comparison operators behave
strangely in those cases? I know that x >= y and x < y are then both
false at least.
C&V, please.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 18 '06 #36

P: n/a
Random832 wrote:

OT: C++ misses entirely the point of having void * - I think, though,
that it doesn't actually forbid NULL expanding to ((void*)0) - a
compiler could special-case this to not be an error when assigned to
other pointers.

It does forbid that, for the very good reason that there is no implicit
conversion from void* to any other pointer. That's why a cast is
required for malloc() in C++.

Were NULL defined as that way, it would require diagnostics every time
it was assigned to a non-void pointer.


Brian
Dec 18 '06 #37

P: n/a
2006-12-18 <_s******************************@bt.com>,
Richard Heathfield wrote:
Random832 said:
>2006-12-18 <P8******************************@bt.com>,
Richard Heathfield wrote:
>>>[...] Another question whether it's always true that:
x==y === !(x!=y)

It is. x!=y yields 0 if they are equivalent, but 1 if they are not. !0 is
1, and !1 is 0. So !(x!=y) yields 1 if they are equivalent, but 0 if they
are not, just like x==y.

What if x is not a number?

If it's not a number, it's a pointer. If it's a pointer, so is y.
Sorry I wasn't clear; by "not a number", I meant "Not a Number".
If the pointers point to the same object, they will compare equal (whether
or not they have the same object representation).
>Don't the comparison operators behave
strangely in those cases? I know that x >= y and x < y are then both
false at least.

C&V, please.
OK, C doesn't specify this. I think that if __STDC_IEC_559__ is defined
though, it's needed.

Apparently != is always true, rather than always false, when presented
with a NAN.

C itself, without IEC 559, apparently only requires "1 if the specified
relation is true and 0 if it is false", without defining in what
circumstances a given relation is true or false (since, in all cases not
involving NANs, it should be self-evident)

Dec 18 '06 #38

P: n/a
Random832 said:
2006-12-18 <_s******************************@bt.com>,
Richard Heathfield wrote:
>Random832 said:
<snip>
>>>
What if x is not a number?

If it's not a number, it's a pointer. If it's a pointer, so is y.

Sorry I wasn't clear; by "not a number", I meant "Not a Number".
Oh, I see! :-) In that case, I'll duck. My knowledge of FPA isn't
sufficient for me to wax confident about NaNs because, in Real Life, I have
had very little use for FPA of any complexity. I suppose I could schildt my
way through the docs for you, but what would be the point of that?

<snip>

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 18 '06 #39

P: n/a
2006-12-18 <4u*************@mid.individual.net>,
Default User wrote:
Random832 wrote:

>OT: C++ misses entirely the point of having void * - I think, though,
that it doesn't actually forbid NULL expanding to ((void*)0) - a
compiler could special-case this to not be an error when assigned to
other pointers.


It does forbid that, for the very good reason that there is no implicit
conversion from void* to any other pointer.
Right. Like I said, it misses the point of having void * at all.
Dec 18 '06 #40

P: n/a
Random832 wrote:
2006-12-18 <4u*************@mid.individual.net>,
Default User wrote:
Random832 wrote:

OT: C++ misses entirely the point of having void * - I think,
though, >that it doesn't actually forbid NULL expanding to
((void*)0) - a >compiler could special-case this to not be an error
when assigned to >other pointers.


It does forbid that, for the very good reason that there is no
implicit conversion from void* to any other pointer.

Right. Like I said, it misses the point of having void * at all.
No, it doesn't. It provides a way to pass any pointer INTO a function.
So at best you could say it misses half the point of a void*.

In actual practice, void* isn't used much in C++. Generally you use
function overloading or pointers to a family of types, relying on
runtime polymorphism.


Brian
Dec 18 '06 #41

P: n/a
Default User wrote:
Random832 wrote:
2006-12-18 <4u*************@mid.individual.net>,
Default User wrote:
Random832 wrote:
>OT: C++ misses entirely the point of having void *
It does forbid that, for the very good reason that there is no
implicit conversion from void* to any other pointer.
Right. Like I said, it misses the point of having void * at all.

No, it doesn't. It provides a way to pass any pointer INTO a function.
You could do that much with a pointer to char,
before there was such a keyword as "void", in the 1970's, man!
So at best you could say it misses half the point of a void*.
In actual practice, void* isn't used much in C++.
--
pete
Dec 18 '06 #42

P: n/a
pete wrote:
Default User wrote:
Random832 wrote:
2006-12-18 <4u*************@mid.individual.net>,
Default User wrote:
Random832 wrote:
OT: C++ misses entirely the point of having void *
It does forbid that, for the very good reason that there is no
implicit conversion from void* to any other pointer.
>
Right. Like I said, it misses the point of having void * at all.
No, it doesn't. It provides a way to pass any pointer INTO a
function.

You could do that much with a pointer to char,
before there was such a keyword as "void", in the 1970's, man!
Not without casting every usage. That's what Random832 was complaining
about.

Brian
Dec 19 '06 #43

This discussion thread is closed

Replies have been disabled for this discussion.