Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

calloc working inside the for loop but not outside

5 views
Skip to first unread message

Harshith

unread,
Nov 18, 2009, 4:43:11 PM11/18/09
to
Can someone kindly point out to me why the following

corners = (CvPoint2D32f **) calloc (ncams, sizeof
(CvPoint2D32f*));
for (i=0; i<ncams; i++) {
assert (corners[i] = (CvPoint2D32f *) calloc (board_corners,
sizeof (CvPoint2D32f)));
}

Harshith

unread,
Nov 18, 2009, 4:47:07 PM11/18/09
to

Sorry the above post is unfinished, Why is the following not working?

CvPoint2D32f** corners = (CvPoint2D32f **) calloc (ncams, sizeof


(CvPoint2D32f*));
for (i=0; i<ncams; i++) {

corners[i] = (CvPoint2D32f *) calloc (board_corners, sizeof

(CvPoint2D32f));
}

//corners[0] = 0 here

but the following works!


corners = (CvPoint2D32f **) calloc (ncams, sizeof
(CvPoint2D32f*));

corners[0] = (CvPoint2D32f *) calloc (board_corners, sizeof
(CvPoint2D32f));
corners[1] = (CvPoint2D32f *) calloc (board_corners, sizeof
(CvPoint2D32f));

//corners[0] != 0 here

I thought it was the same statement with or without the loop. Can
someone tell me where i am going wrong?

Eric Sosman

unread,
Nov 18, 2009, 5:02:29 PM11/18/09
to
Harshith wrote:
> On Nov 18, 4:43 pm, Harshith <harshi....@gmail.com> wrote:
>> Can someone kindly point out to me why the following
>>
>> corners = (CvPoint2D32f **) calloc (ncams, sizeof
>> (CvPoint2D32f*));
>> for (i=0; i<ncams; i++) {
>> assert (corners[i] = (CvPoint2D32f *) calloc (board_corners,
>> sizeof (CvPoint2D32f)));

You *really* don't want to do the allocation inside an
assert(). In the full code below, I'm glad to see you don't.

>> }
>
> Sorry the above post is unfinished, Why is the following not working?
>
> CvPoint2D32f** corners = (CvPoint2D32f **) calloc (ncams, sizeof
> (CvPoint2D32f*));
> for (i=0; i<ncams; i++) {
> corners[i] = (CvPoint2D32f *) calloc (board_corners, sizeof
> (CvPoint2D32f));
> }
>
> //corners[0] = 0 here
>
> but the following works!
> corners = (CvPoint2D32f **) calloc (ncams, sizeof
> (CvPoint2D32f*));
>
> corners[0] = (CvPoint2D32f *) calloc (board_corners, sizeof
> (CvPoint2D32f));
> corners[1] = (CvPoint2D32f *) calloc (board_corners, sizeof
> (CvPoint2D32f));
>
> //corners[0] != 0 here
>
> I thought it was the same statement with or without the loop. Can
> someone tell me where i am going wrong?

Most probably, ncams <= 0 and the loop body never executes.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Harshith

unread,
Nov 18, 2009, 7:53:19 PM11/18/09
to
Hi Eric, thanks for the response.

ncams = 2. So the loop exectues. And why do you say i shouldn't do
allocation inside assert?
I thought the assert () is called only after allocation and its
equivalant to

corners[i] = (CvPoint2D32f *) calloc (board_corners, sizeof
(CvPoint2D32f));

assert (corners[i]);

it isn't?

> esos...@ieee-dot-org.invalid

Richard Heathfield

unread,
Nov 18, 2009, 8:03:46 PM11/18/09
to
In
<b495797f-5d78-42a7...@g31g2000vbr.googlegroups.com>,
Harshith wrote:

> And why do you say i shouldn't do allocation inside assert?

The whole point of assertions is that you can turn them off, by
defining NDEBUG. If you put an allocation inside an assertion,
turning off the assertion turns off the allocation, too!

Use assertions to check program assumptions. If an assertion fails, it
should be because there is a bug in the program. A memory allocation
failure is not in itself a program bug.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within

Keith Thompson

unread,
Nov 18, 2009, 7:58:23 PM11/18/09
to
Harshith <harsh...@gmail.com> writes:
> Hi Eric, thanks for the response.
>
> ncams = 2. So the loop exectues. And why do you say i shouldn't do
> allocation inside assert?
> I thought the assert () is called only after allocation and its
> equivalant to
>
> corners[i] = (CvPoint2D32f *) calloc (board_corners, sizeof
> (CvPoint2D32f));
> assert (corners[i]);
>
> it isn't?
[...]

Please don't top-post. See:
http://www.caliburn.nl/topposting.html
http://www.cpax.org.uk/prg/writings/topposting.php

The argument to assert() should never have side effects. The purpose
is to provide run-time checks that can be disabled. If the macro
NDEBUG is defined, then the assert() call effectively vanishes,
and your assignment goes away.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Richard Heathfield

unread,
Nov 18, 2009, 8:15:20 PM11/18/09
to
In <lntywrw...@nuthaus.mib.org>, Keith Thompson wrote:

<snip>



> The argument to assert() should never have side effects.

I disagree. I would agree that the argument to assert() should never
have side effects that are required for the correct functioning of
the production version of the program. But consider:

assert(tree_is_intact(foo_tree));

which might well have the side effect of writing details of tree
corruption to a (debug-only) log file. I would argue that this is a
perfectly legitimate use of assert().

<snip>

Keith Thompson

unread,
Nov 18, 2009, 8:23:01 PM11/18/09
to
Richard Heathfield <r...@see.sig.invalid> writes:
> In <lntywrw...@nuthaus.mib.org>, Keith Thompson wrote:
>
> <snip>
>
>> The argument to assert() should never have side effects.
>
> I disagree. I would agree that the argument to assert() should never
> have side effects that are required for the correct functioning of
> the production version of the program. But consider:
>
> assert(tree_is_intact(foo_tree));
>
> which might well have the side effect of writing details of tree
> corruption to a (debug-only) log file. I would argue that this is a
> perfectly legitimate use of assert().
>
> <snip>

Conceded.

Eric Sosman

unread,
Nov 18, 2009, 9:13:38 PM11/18/09
to
Harshith wrote:

[Please don't top-post. I tried to rearrange your response into
a more readable form, but failed.]

1) Why not allocate inside assert()? Because assert()
can be turned into a no-op by an "innocent" definition of
the preprocessor symbol NDEBUG. In fact, this is done rather
commonly: You do your testing with the assert() calls enabled,
and then you define NDEBUG to remove them and their overhead
in the production version. And then, if the assert() contained
anything with a side-effect -- like an allocation, or an I/O
operation -- that side-effect suddenly disappears from the
program, and what you tested no longer resembles what you ship.

2) So ncams == 2, eh? Well, if you say so. On what you've
shown I'm not inclined to believe you, but surely you know
better than I. I wonder what evidence you have to support the
contention ...

--
Eric Sosman
eso...@ieee-dot-org.invalid

pete

unread,
Nov 19, 2009, 8:49:01 AM11/19/09
to
Harshith wrote:
> On Nov 18, 4:43 pm, Harshith <harshi....@gmail.com> wrote:
>
>>Can someone kindly point out to me why the following
>>
>> corners = (CvPoint2D32f **) calloc (ncams, sizeof
>>(CvPoint2D32f*));
>> for (i=0; i<ncams; i++) {
>> assert (corners[i] = (CvPoint2D32f *) calloc (board_corners,
>>sizeof (CvPoint2D32f)));
>> }

I would write that this way:

CvPoint2D32f **corners = calloc(ncams, sizeof *corners);

if (corners != NULL) {
for (i = 0; i != ncams; ++i) {
corners[i] = calloc(board_corners, sizeof *corners[i]);
if (corners[i] == NULL) {

>
>
> Sorry the above post is unfinished, Why is the following not working?
>
> CvPoint2D32f** corners = (CvPoint2D32f **) calloc (ncams, sizeof
> (CvPoint2D32f*));
> for (i=0; i<ncams; i++) {
> corners[i] = (CvPoint2D32f *) calloc (board_corners, sizeof
> (CvPoint2D32f));
> }
>
> //corners[0] = 0 here
>

I am unable to duplicate any loop related problems with allocation.

/* BEGIN new.c output */

zero
one

/* END new.c output */

/* BEGIN new.c */

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

#define NMEMB(A) (sizeof (A) / sizeof *(A))

typedef char CvPoint2D32f;

void free_corners(CvPoint2D32f** corners, size_t nmemb);
void print_corners(CvPoint2D32f** corners, size_t nmemb);

int main(void)
{
unsigned i;
char strings[][sizeof "seven"] = {
"zero", "one"
/*,"two","three","four",
"five","six","seven","eight","nine","ten"
*/
};
size_t ncams = NMEMB(strings);
size_t board_corners = sizeof *strings;
CvPoint2D32f **corners = calloc(ncams, sizeof *corners);

if (corners != NULL) {
for (i = 0; i != ncams; ++i) {
corners[i] = calloc(board_corners, sizeof *corners[i]);
if (corners[i] == NULL) {
printf("corners[%u] == NULL\n\n", i);
break;
}
strcpy(corners[i], strings[i]);
}
} else {
i = 0;
puts("corners == NULL\n");
}
puts("/* BEGIN new.c output */\n");
print_corners(corners, i);
free_corners(corners, i);
puts("\n/* END new.c output */\n");
return 0;
}

void free_corners(CvPoint2D32f** corners, size_t nmemb)
{
while (nmemb-- != 0) {
free(corners[nmemb]);
}
free(corners);
}

void print_corners(CvPoint2D32f** corners, size_t nmemb)
{
size_t index;

for (index = 0; index != nmemb; ++index) {
puts(corners[index]);
}
}

/* END new.c */

--
pete

Herbert Rosenau

unread,
Nov 23, 2009, 4:17:05 PM11/23/09
to
On Wed, 18 Nov 2009 21:47:07 UTC, Harshith <harsh...@gmail.com>
wrote:

> On Nov 18, 4:43ᅵpm, Harshith <harshi....@gmail.com> wrote:
> > Can someone kindly point out to me why the following
> >

> > ᅵ ᅵ corners = (CvPoint2D32f **) calloc (ncams, sizeof
> > (CvPoint2D32f*));
> > ᅵ ᅵ for (i=0; i<ncams; i++) {
> > ᅵ ᅵ ᅵ ᅵ assert (corners[i] = (CvPoint2D32f *) calloc (board_corners,
> > sizeof (CvPoint2D32f)));
> > ᅵ ᅵ }
>

Never use assert when you're not sure what you're doing - and here it
is clear that you not even has an idea why and how you have to use
assert. So you're lying to the compiler that you'll call calloc - but
in golden code you simply does NOT letting the program crash by any
customer but never in your debug environment.

Never ever cast the result of a function retuning pointer to void -
this cast is always a lie - and lying to the compiler will get ist
revange!

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2R Deutsch ist da!

Herbert Rosenau

unread,
Nov 23, 2009, 4:17:05 PM11/23/09
to
On Wed, 18 Nov 2009 21:43:11 UTC, Harshith <harsh...@gmail.com>
wrote:

Never ever cast result from a function returning pointer to void! This
will miseragbly whenever you've forgotten to #include <stdlib.h>. In
any other case it makes no sense anyway.

Keith Thompson

unread,
Nov 23, 2009, 4:28:05 PM11/23/09
to
"Herbert Rosenau" <os2...@pc-rosenau.de> writes:
> On Wed, 18 Nov 2009 21:47:07 UTC, Harshith <harsh...@gmail.com>
> wrote:
>
>> On Nov 18, 4:43 pm, Harshith <harshi....@gmail.com> wrote:
>> > Can someone kindly point out to me why the following
>> >
>> >     corners = (CvPoint2D32f **) calloc (ncams, sizeof
>> > (CvPoint2D32f*));
>> >     for (i=0; i<ncams; i++) {
>> >         assert (corners[i] = (CvPoint2D32f *) calloc (board_corners,
>> > sizeof (CvPoint2D32f)));
>> >     }
>>
>
> Never use assert when you're not sure what you're doing - and here it
> is clear that you not even has an idea why and how you have to use
> assert. So you're lying to the compiler that you'll call calloc - but
> in golden code you simply does NOT letting the program crash by any
> customer but never in your debug environment.

Several of us have already explained exactly *why* this is a bad idea.
Telling the OP he shouldn't do this because he obviously doesn't know
what he's doing is hardly useful.

> Never ever cast the result of a function retuning pointer to void -
> this cast is always a lie - and lying to the compiler will get ist
> revange!

Nonsense. Casting is unnecessary, but as long as the cast is to the
correct type, it merely makes explicit the conversion that would have
been done implicitly.

It is not "lying to the compiler", it's merely giving the compiler
*correct* information that it doesn't need.

Keith Thompson

unread,
Nov 23, 2009, 4:29:55 PM11/23/09
to
"Herbert Rosenau" <os2...@pc-rosenau.de> writes:
> On Wed, 18 Nov 2009 21:47:07 UTC, Harshith <harsh...@gmail.com>
> wrote:
>
>> On Nov 18, 4:43 pm, Harshith <harshi....@gmail.com> wrote:
>> > Can someone kindly point out to me why the following
>> >
>> >     corners = (CvPoint2D32f **) calloc (ncams, sizeof
>> > (CvPoint2D32f*));
>> >     for (i=0; i<ncams; i++) {
>> >         assert (corners[i] = (CvPoint2D32f *) calloc (board_corners,
>> > sizeof (CvPoint2D32f)));
>> >     }
>>
>
> Never use assert when you're not sure what you're doing - and here it
> is clear that you not even has an idea why and how you have to use
> assert. So you're lying to the compiler that you'll call calloc - but
> in golden code you simply does NOT letting the program crash by any
> customer but never in your debug environment.

Several of us have already explained exactly *why* this is a bad idea.


Telling the OP he shouldn't do this because he obviously doesn't know
what he's doing is hardly useful.

> Never ever cast the result of a function retuning pointer to void -

> this cast is always a lie - and lying to the compiler will get ist
> revange!

Nonsense. Casting is unnecessary, but as long as the cast is to the

Richard

unread,
Nov 23, 2009, 4:33:16 PM11/23/09
to
"Herbert Rosenau" <os2...@pc-rosenau.de> writes:

> On Wed, 18 Nov 2009 21:43:11 UTC, Harshith <harsh...@gmail.com>
> wrote:
>
>> Can someone kindly point out to me why the following
>>
>> corners = (CvPoint2D32f **) calloc (ncams, sizeof
>> (CvPoint2D32f*));
>> for (i=0; i<ncams; i++) {
>> assert (corners[i] = (CvPoint2D32f *) calloc (board_corners,
>> sizeof (CvPoint2D32f)));
>> }
>
> Never ever cast result from a function returning pointer to void! This
> will miseragbly whenever you've forgotten to #include <stdlib.h>. In
> any other case it makes no sense anyway.

Wrong. It might. And then only IF you "forget" to include stdlib.h....


--
"Avoid hyperbole at all costs, its the most destructive argument on
the planet" - Mark McIntyre in comp.lang.c

Kaz Kylheku

unread,
Nov 23, 2009, 7:29:20 PM11/23/09
to
On 2009-11-23, Herbert Rosenau <os2...@pc-rosenau.de> wrote:
> On Wed, 18 Nov 2009 21:43:11 UTC, Harshith <harsh...@gmail.com>
> wrote:
>
>> Can someone kindly point out to me why the following
>>
>> corners = (CvPoint2D32f **) calloc (ncams, sizeof
>> (CvPoint2D32f*));
>> for (i=0; i<ncams; i++) {
>> assert (corners[i] = (CvPoint2D32f *) calloc (board_corners,
>> sizeof (CvPoint2D32f)));
>> }
>
> Never ever cast result from a function returning pointer to void!

Here is a piece of code which has an important side effect taking place in the
argument expression of an assert, and you're reacting to the cast of the calloc
return value!

Is this a case of trying too hard to fit into c.l.c?

> Never ever cast result from a function returning pointer to void! This
> will miseragbly whenever you've forgotten to #include <stdlib.h>. In
> any other case it makes no sense anyway.

Should the implementation of a statically typed language, when confronted with
an undeclared identifier, simply make up a type, assign that type to the
identifier, and let that identifier be called as a function---without issuing
a diagnostic?

Your code may sometimes have to be ported to a compiler which behaves this way,
but what excuse is there for /developing/ with such a tool?

What if you forget some other headers? The same crappy compiler will let you do
this:

/* didn't include <math.h> */

double y = fabs(x);

Oops, fabs is not declared and so assumed to return int. But here,
int is assignment compatible with double. You don't get a diagnostic.

Oliver Jackson

unread,
Nov 24, 2009, 12:18:12 AM11/24/09
to
On Nov 23, 1:17 pm, "Herbert Rosenau" <os2...@pc-rosenau.de> wrote:
> On Wed, 18 Nov 2009 21:47:07 UTC, Harshith <harshi....@gmail.com>
> wrote:

>
> > On Nov 18, 4:43 pm, Harshith <harshi....@gmail.com> wrote:
> > > Can someone kindly point out to me why the following
>
> > >     corners = (CvPoint2D32f **) calloc (ncams, sizeof
> > > (CvPoint2D32f*));
> > >     for (i=0; i<ncams; i++) {
> > >         assert (corners[i] = (CvPoint2D32f *) calloc (board_corners,
> > > sizeof (CvPoint2D32f)));
> > >     }
>
> Never use assert when you're not sure what you're doing - and here it
> is clear that you not even has an idea why and how you have to use
> assert. So you're lying to the compiler that you'll call calloc - but
> in golden code you simply does NOT letting the program crash by any
> customer but never in your debug environment.
>
> Never ever cast the result of a function retuning pointer to void -
> this cast is always a lie - and lying to the compiler will get ist
> revange!

YO herb I hear you brother but thats a bit rough dog

Herbert Rosenau

unread,
Nov 24, 2009, 5:00:05 PM11/24/09
to
On Mon, 23 Nov 2009 21:28:05 UTC, Keith Thompson <ks...@mib.org>
wrote:

> "Herbert Rosenau" <os2...@pc-rosenau.de> writes:
> > On Wed, 18 Nov 2009 21:47:07 UTC, Harshith <harsh...@gmail.com>
> > wrote:
> >

> >> On Nov 18, 4:43ᅵpm, Harshith <harshi....@gmail.com> wrote:
> >> > Can someone kindly point out to me why the following
> >> >

> >> > ᅵ ᅵ corners = (CvPoint2D32f **) calloc (ncams, sizeof
> >> > (CvPoint2D32f*));


> >> > ᅵ ᅵ for (i=0; i<ncams; i++) {

> >> > ᅵ ᅵ ᅵ ᅵ assert (corners[i] = (CvPoint2D32f *) calloc (board_corners,
> >> > sizeof (CvPoint2D32f)));
> >> > ᅵ ᅵ }


> >>
> >
> > Never use assert when you're not sure what you're doing - and here it
> > is clear that you not even has an idea why and how you have to use
> > assert. So you're lying to the compiler that you'll call calloc - but
> > in golden code you simply does NOT letting the program crash by any
> > customer but never in your debug environment.
>
> Several of us have already explained exactly *why* this is a bad idea.
> Telling the OP he shouldn't do this because he obviously doesn't know
> what he's doing is hardly useful.
>
> > Never ever cast the result of a function retuning pointer to void -
> > this cast is always a lie - and lying to the compiler will get ist
> > revange!
>
> Nonsense. Casting is unnecessary, but as long as the cast is to the
> correct type, it merely makes explicit the conversion that would have
> been done implicitly.
>
> It is not "lying to the compiler", it's merely giving the compiler
> *correct* information that it doesn't need.
>

Oh, the world is not only I86, there are some other implementations
and at least one will assume that a pointer as a return type comes
from another location as plain int.

That results in (dumb cast) malloc(10) tht that the false assumption
malloc returns int has not one single bit in common with that malloc
has returned. So the cast is complete the cause of some unwanted event
- and there will be no diagnostic because the lie that malloc returns
int (as it really does nebver) causes something unwanted.

Again: never cast except you knows exactly why you must cast to get
something right. Suppressing an diagnostic is noways knowing why.

Keith Thompson

unread,
Nov 24, 2009, 9:02:59 PM11/24/09
to
"Herbert Rosenau" <os2...@pc-rosenau.de> writes:
> On Mon, 23 Nov 2009 21:28:05 UTC, Keith Thompson <ks...@mib.org>
> wrote:
>> "Herbert Rosenau" <os2...@pc-rosenau.de> writes:
>> > On Wed, 18 Nov 2009 21:47:07 UTC, Harshith <harsh...@gmail.com>
>> > wrote:
>> >
>> >> On Nov 18, 4:43 pm, Harshith <harshi....@gmail.com> wrote:
>> >> > Can someone kindly point out to me why the following
>> >> >
>> >> >     corners = (CvPoint2D32f **) calloc (ncams, sizeof
>> >> > (CvPoint2D32f*));
>> >> >     for (i=0; i<ncams; i++) {
>> >> >         assert (corners[i] = (CvPoint2D32f *) calloc (board_corners,
>> >> > sizeof (CvPoint2D32f)));
>> >> >     }
>> >>
>> >
>> > Never use assert when you're not sure what you're doing - and here it
>> > is clear that you not even has an idea why and how you have to use
>> > assert. So you're lying to the compiler that you'll call calloc - but
>> > in golden code you simply does NOT letting the program crash by any
>> > customer but never in your debug environment.
>>
>> Several of us have already explained exactly *why* this is a bad idea.
>> Telling the OP he shouldn't do this because he obviously doesn't know
>> what he's doing is hardly useful.
>>
>> > Never ever cast the result of a function retuning pointer to void -
>> > this cast is always a lie - and lying to the compiler will get ist
>> > revange!
>>
>> Nonsense. Casting is unnecessary, but as long as the cast is to the
>> correct type, it merely makes explicit the conversion that would have
>> been done implicitly.
>>
>> It is not "lying to the compiler", it's merely giving the compiler
>> *correct* information that it doesn't need.
>
> Oh, the world is not only I86, there are some other implementations
> and at least one will assume that a pointer as a return type comes
> from another location as plain int.

I was referring to casting the result of malloc() after a proper
"#include <stdlib.h>".

Consider this program:

#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int *ptr = (int*)malloc(sizeof (int));
if (ptr == NULL) {
puts("malloc failed");
}
else {
*ptr = 42;
printf("%d\n", *ptr);
}
return 0;
}

The cast is unnecessary, superfluous, redundant, and unneeded --
as well as being unnecessary. But it is perfectly legal, and it
is *not* "lying to the compiler". It is, as I said, merely giving
the compiler information that it doesn't need. (It also runs the
risk of becoming a lie to the compiler as the code is modified,
but as it stands it is not.)

0 new messages