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

Allocation of memory for Array of Pointers

P: n/a
main()
{
int i;
int *a[2];
a=calloc(4,sizeof(*a));
/* The above code I know will not compile[Lvalue required] .But why
cant I allocate space
for all 4 integers i need to store */
for(i=0;i<2;i++)
a[i]=calloc(2,sizeof(*a));
/* this works fine I know?But why not the earlier one */
}

Dec 27 '05 #1
Share this Question
Share on Google+
21 Replies


P: n/a
Hi,
The reason might be:
You are trying to assign int * to int ** in the frist statement
however, in second stmt you are assigning int * to int * which is a
valid statement.

-Chandan

smartbeginner wrote:
main()
{
int i;
int *a[2];
a=calloc(4,sizeof(*a));
/* The above code I know will not compile[Lvalue required] .But why
cant I allocate space
for all 4 integers i need to store */
for(i=0;i<2;i++)
a[i]=calloc(2,sizeof(*a));
/* this works fine I know?But why not the earlier one */
}


Dec 27 '05 #2

P: n/a
void *calloc(size_t nelem, size_t elsize)

function calloc return a pointer to a space suitably aligned for
storage of any type of objec.

a[i] is a pointer to a integer , but a is a pointer to a space which is
a pointer to a integer.

Dec 27 '05 #3

P: n/a

smartbeginner wrote:
main()
{
int i;
int *a[2];
a=calloc(4,sizeof(*a));
/* The above code I know will not compile[Lvalue required] .But why
cant I allocate space
for all 4 integers i need to store */
for(i=0;i<2;i++)
a[i]=calloc(2,sizeof(*a));
/* this works fine I know?But why not the earlier one */
}


I think you really should go reading the section6 of comp.lang.c FAQ,
http://c-faq.com/aryptr/index.html
as you'v been suggested.

a is an array, a[i] is a pointer.
they are not the same at all.

Dec 27 '05 #4

P: n/a
Forgot to mention that u must typecast the calloc function as its
return type is void * (however some compiler automatically return
pointer type of the type_of_its_second_ argument.)

Dec 27 '05 #5

P: n/a
chandan wrote:
Forgot to mention that u must typecast the calloc function as its
return type is void * (however some compiler automatically return
pointer type of the type_of_its_second_ argument.)

The standard calloc *always* returns void*. And you do not need the
cast. Read through the FAQ and numerous old posts in the archive as to
why you don't need a cast.

You did quote in your previous reply... you forgot here.
FYI: <http://cfaj.freeshell.org/google/>
Also see the welcome note about bottom posting.

--
(Welcome) http://www.ungerhu.com/jxh/clc.welcome.txt
(clc FAQ) http://c-faq.com/
Dec 27 '05 #6

P: n/a
"chandan" <ch*********@gmail.com> writes:
Forgot to mention that u must typecast the calloc function as its
return type is void * (however some compiler automatically return
pointer type of the type_of_its_second_ argument.)


No. calloc() returns a result of type void*, but it's implicitly
converted to the target pointer type. An explicit cast is unnecessary
and can mask errors (such as forgetting the required "#include <stdlib.h>"
or compiling C code with a C++ compiler).

Please read <http://cfaj.freeshell.org/google/>, and don't use silly
abbreviations like "u" for "you".

--
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 27 '05 #7

P: n/a
chandan wrote:
Forgot to mention that u must typecast the calloc function as its
return type is void * (however some compiler automatically return
pointer type of the type_of_its_second_ argument.)


This is simply a pile of manure. Casting the return value from
calloc(), malloc(), or realloc() is unnecessart and serves only to hide
errors.

*All* confoming library implementations will return void * (_never_ the
type of an argument), and that void * pointer will seamlessly be
converted to a pointer to the appropiate type.

Pay no attention to chandon; he knows nothing.
Dec 27 '05 #8

P: n/a
smartbeginner wrote:
main()
{
int i;
int *a[2];
The above sentece declares a as an array of two pointers to integers,
which I think it's not what you want.
a=calloc(4,sizeof(*a));
Now you try to assign a pointer to an array, sth that cannot be done.
As you said an Lvalue is required in the left side of an assignment,
and an array identifier is not an Lvalue.
/* The above code I know will not compile[Lvalue required] .But why
cant I allocate space
for all 4 integers i need to store */
for(i=0;i<2;i++)
a[i]=calloc(2,sizeof(*a));
/* this works fine I know?But why not the earlier one */
}


I think that what you wanted to do was something along the lines of:

#include <stdlib.h>

int main (void) {
int (*a)[2]; /*Declare a as a pointer to an array of two integers*/
a = malloc(2 * sizeof(*a));
return 0;
}

Dec 27 '05 #9

P: n/a

smartbeginner wrote:
main()
Implicit typing of main() is no longer supported in the latest
standard, so start using either

int main(void)

or

int main(int argc, char **argv)
{
int i;
int *a[2];
a=calloc(4,sizeof(*a));
/* The above code I know will not compile[Lvalue required] .But why
cant I allocate space
for all 4 integers i need to store */
You have declared a as a 2-element array of pointers to int; as such,
you don't need to allocate any memory for a itself.

You're getting the error because a is an array type, not a pointer
type, and array type objects are not modifiable.

Secondly, how are you going to store 4 items into a 2-element array?
for(i=0;i<2;i++)
a[i]=calloc(2,sizeof(*a));
/* this works fine I know?But why not the earlier one */
}


Because each element of a is a pointer type.

It would really help if you would explain exactly what you're trying to
do here. You're obviously confused about something, but without
knowing what you're trying to accomplish, I'm not sure I can help.

It sounds like you're trying to allocate 2 arrays of 2 elements each.
If that is the case, here are a couple of ways to do it:

/* First method */

#include <stdlib.h>

int main(void)
{
int **a;

/*
* Allocate enough memory to hold two int * objects
*/
a = calloc(2, sizeof *a); /* or malloc(2 * sizeof *a); */
if (a)
{
int i;
for (i = 0; i < 2; i++)
{
/*
* Allocate enough memory to hold two int objects
*/
a[i] = calloc(2, sizeof **a); /* or malloc(2 * sizeof **a);
*/
if (a[i])
{
/* assign a[i][0] and a[i][1] */
}
else
{
printf("Memory allocation failed for a[%d]\n", i);
}
}
}
else
{
printf("Memory allocation failed for a\n");
}
return 0;
}

/* Second method */

#include <stdlib.h>

int main(void)
{
int (*a)[2];

a = calloc(2, sizeof *a); /* or malloc(2 * sizeof *a); */
if (a)
{
int i;
for (i = 0; i < 2; i++)
{
/* assign a[i][0] and a[i][1] */
}
}

return 0;
}

Dec 27 '05 #10

P: n/a

smartbeginner wrote:
main()
{
int i;
int *a[2];
a=calloc(4,sizeof(*a));
/* The above code I know will not compile[Lvalue required] .But why
cant I allocate space
for all 4 integers i need to store */
for(i=0;i<2;i++)
a[i]=calloc(2,sizeof(*a));
/* this works fine I know?But why not the earlier one */
}


The First one won't compile because a is an array and is NOT a pointer.

Dec 27 '05 #11

P: n/a
chandan wrote:

Forgot to mention that u must typecast the calloc function as
its return type is void * (however some compiler automatically
return pointer type of the type_of_its_second_ argument.)


Please do not top-post, do not use silly confusing abbreviations
(such as "u" and the ilk), and do include context.

In addition your advice is wrong. There is never any need to cast
the return values from calloc, malloc, and friends. There IS a
need to #include the appropriate header, such as stdlib.h.

--
Some informative links:
news:news.announce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html

Dec 27 '05 #12

P: n/a
"Chuck F." wrote:

chandan wrote:

Forgot to mention that u must typecast the calloc function as
its return type is void * (however some compiler automatically
return pointer type of the type_of_its_second_ argument.)
Please do not top-post, do not use silly confusing abbreviations
(such as "u" and the ilk), and do include context.

....and do *not* generally be an asshole in any other way. ;-)
In addition your advice is wrong. There is never any need to cast
the return values from calloc, malloc, and friends. There IS a
need to #include the appropriate header, such as stdlib.h.

True, you don't need the cast. But if you are stubborn, the cast
is *not* prohibited by the C standard. ;-)

--
+----------------------------------------------------------------+
| Charles and Francis Richmond richmond at plano dot net |
+----------------------------------------------------------------+
Dec 27 '05 #13

P: n/a
i wrote:
Forgot to mention that u must typecast the calloc function as its
return type is void * (however some compiler automatically return
pointer type of the type_of_its_second_ argument.)
i am sorry for the silly abbreviations, i had used. Thanks, for the
advice.

Martin Ambuhl wrote:Pay no attention to chandon; he knows nothing.
I never told that i know everything. i am a beginner to C and, really,
i don't know anything, as such, about C. I got my first lesson and I am
eager to learn more.

Keith wrote:No. calloc() returns a result of type void*, but it's implicitly
converted to the target pointer type. An explicit cast is unnecessary
and can mask errors (such as forgetting the required "#include <stdlib.h>"
or compiling C code with a C++ compiler).


In my case, i was trying to compile this code with a C++ compiler. But,
please, can you elaborate how it masks the error and how stdlib.h helps
in conversion of type void * to target pointer type? i mean, how it
determines the target pointer type, if i am using a C compiler.

Dec 28 '05 #14

P: n/a
chandan said:
Keith wrote:
No. calloc() returns a result of type void*, but it's implicitly
converted to the target pointer type. An explicit cast is unnecessary
and can mask errors (such as forgetting the required "#include <stdlib.h>"
or compiling C code with a C++ compiler).
In my case, i was trying to compile this code with a C++ compiler.


That's always a mistake. You wouldn't try to compile Algol with a Pascal
compiler, so why compile C with a C++ compiler?
But,
please, can you elaborate how it masks the error and how stdlib.h helps
It provides a full prototype for calloc, thus telling the compiler that
malloc returns void *.
in conversion of type void * to target pointer type?
By telling the compiler that calloc returns void *, the prototype assists in
the generation of correct code. Without the prototype, the compiler would
be forced to assume that calloc returns int (which calloc doesn't in fact
return).

In the following example, I use malloc rather than calloc, for the simple
reason that experienced C programmers hardly ever use calloc as its side
effect is generally (but not quite always) unnecessary, but the reasoning
is identical.
i mean, how it
determines the target pointer type, if i am using a C compiler.


#include <stdio.h> /* for printf prototype */
#include <stdlib.h> /* for malloc prototype */

typedef int T; /* any object type will do here */

int main(void)
{
T *p; /* compiler now knows p has type T *, so all is well */
size_t n = 42; /* compiler now knows n has type size_t, so all is well */
p = malloc(n * sizeof *p); /* malloc returns void *, and the compiler
* knows that p has type T *, and the
* compiler knows how to convert
* between void * and T *, so there is
* no problem here. */
if(p != NULL)
{
printf("Yes, I got the memory. It's at %p.\n", (void *)p);
free(p);
}

return 0;
}

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Dec 28 '05 #15

P: n/a
chandan wrote:
i wrote:
Forgot to mention that u must typecast the calloc function as its
return type is void * (however some compiler automatically return
pointer type of the type_of_its_second_ argument.)

i am sorry for the silly abbreviations, i had used. Thanks, for the
advice.

Martin Ambuhl wrote:
Pay no attention to chandon; he knows nothing.

I never told that i know everything.


*Everything* you wrote was wrong. It is not a question of your knowing
everything: everything you "know" is wrong and you have no business
inflicting your ignorance on others as advice.

Dec 28 '05 #16

P: n/a
Richard wrote:
/* malloc returns void *, and the compiler
* knows that p has type T *, and the
* compiler knows how to convert
* between void * and T *, so there is
* no problem here. */


Richard, i got your point. But, still I have a little confusion.

In section 7.8.5 of K&R, they mention that

The pointer returned by malloc or calloc has the proper alignment for
the object in question, but it must be cast into the appropriate type,
as in
int *ip;
ip = (int *) calloc(n, sizeof(int));

Is the above given statement is no longer valid? And, if it is valid
statement, then which point i am missing, now?

Dec 28 '05 #17

P: n/a
chandan said:
Richard, i got your point. But, still I have a little confusion.

In section 7.8.5 of K&R, they mention that

The pointer returned by malloc or calloc has the proper alignment for
the object in question, but it must be cast into the appropriate type,


Yes, K&R got it wrong. The cast is not required. The following quote is from
Dennis Ritchie's "errata" site:

"142(6.5, toward the end): The remark about casting the return value of
malloc ("the proper method is to declare ... then explicitly coerce") needs
to be rewritten. The example is correct and works, but the advice is
debatable in the context of the 1988-1989 ANSI/ISO standards. It's not
necessary (given that coercion of void * to ALMOSTANYTYPE * is automatic),
and possibly harmful if malloc, or a proxy for it, fails to be declared as
returning void *. The explicit cast can cover up an unintended error. On
the other hand, pre-ANSI, the cast was necessary, and it is in C++ also."

Taken from: <http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html>

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Dec 28 '05 #18

P: n/a
Martin Ambuhl wrote:
*Everything* you wrote was wrong. It is not a question of your knowing
everything: everything you "know" is wrong and you have no business
inflicting your ignorance on others as advice.
Cool down, man!! Why, you are showing so much aggression?
everything: everything you "know" is wrong.


No, not now.... :-). Feeling happy.

Dec 28 '05 #19

P: n/a
Richard wrote:
Taken from: <http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html>


Thank you, very much, for the link. :-)

Dec 28 '05 #20

P: n/a
chandan wrote:
Martin Ambuhl wrote:
*Everything* you wrote was wrong. It is not a question of your knowing
everything: everything you "know" is wrong and you have no business
inflicting your ignorance on others as advice.

Cool down, man!! Why, you are showing so much aggression?


Don't patronize me, you idiot. You are the one that not only posted
bullshit but then tried to justify your doing it.
There is little worse than someone who writes something like: Forgot to mention that u must typecast the calloc function as its
return type is void * (however some compiler automatically return
pointer type of the type_of_its_second_ argument.)


You tell someone that they *must* do something. What you tell them they
*must* do is not only not required, but bad practice. Further, the
parenthesized sentence is hopelessly confused: it is the library
function that returns a value, not the compiler, and neither the library
function nor the compiler looks at an argument type to decide what to
return.

You pose as someone who knows, and prescibe to others. You have no
right either to claiming knowledge or to prescribing to others. Giving
bullshit advice is a sin; claiming that it *must* be followed is a
mortal sin.
everything: everything you "know" is wrong.


No, not now.... :-). Feeling happy.


Turn you home-schooling psychology certification in for a refund. The
day that a know-nothing bullshitter like you has any business being
patronizing to me is a long way off.

Dec 28 '05 #21

P: n/a
"chandan" <ch*********@gmail.com> writes:
Martin Ambuhl wrote:
*Everything* you wrote was wrong. It is not a question of your knowing
everything: everything you "know" is wrong and you have no business
inflicting your ignorance on others as advice.


Cool down, man!! Why, you are showing so much aggression?
everything: everything you "know" is wrong.


No, not now.... :-). Feeling happy.


At your current level of expertise, you need to acknowledge that your
advice isn't necessarily correct. You've posted misinformation
(unintentionally, I'm sure), and you've phrased it in a way that
implies you're very certain that you're correct. This is positively
dangerous.

If you want to post a guess while making it very clear that it's only
a guess, that's ok; there are plenty of people who can correct you if
you're wrong. (We all make mistakes, after all.) But posting bad
information while claiming certainty is far worse than making an
honest mistake.

--
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 28 '05 #22

This discussion thread is closed

Replies have been disabled for this discussion.