473,379 Members | 1,542 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,379 software developers and data experts.

calloc

Sorry for the re-post, but my previous question was left unanswered.

I have a question about the appropriateness of calloc. Consider an array of
pointers to structs which need to be allocated space on the heap, for example:

typedef struct myStruct *PMYSTRUCT;
struct myStruct
{
int i;
int j;
...etc...
}

PMYSTRUCT myArray[10];

While I know I can point and allocate each element manually my looping mallocs,
I wonder if calloc will do what I want. Will executing "myArray = calloc(10,
sizeof(myStruct));" allocate 10 myStructs somewhere on the heap and put pointers
to each one in the myArray array, or will it allocate the myStructs and point
myArray[0] to it, thereby making myArray[1] point somewhere inside the 1st
myStruct and messing up everything?

I hope that's clear enough,
Koster.
Nov 13 '05 #1
5 3604

On Fri, 12 Sep 2003, Koster wrote:

I have a question about the appropriateness of calloc. Consider an array
of pointers to structs which need to be allocated space on the heap, for
example:

typedef struct myStruct *PMYSTRUCT;
struct myStruct
{
int i;
int j;
...etc...
}

PMYSTRUCT myArray[10];
Better if you have a question *not* to use this sort of obfuscating
typedef. I started this response intending to point out that 'myArray'
was *already* an array of 'myStruct', so you couldn't assign anything
to it. In fact, it's an array of *pointers* to 'myStruct' -- so you
still can't assign anything to it, but you *do* have to initialize the
elements correctly.
Writing

struct myStruct *myArray[10];

would have made your question (and your code) much clearer.
While I know I can point and allocate each element manually [by] looping
mallocs, I wonder if calloc will do what I want. Will executing
"myArray = calloc(10, sizeof(myStruct));" allocate 10 myStructs somewhere
on the heap and put pointers to each one in the myArray array, or will
it allocate the myStructs and point myArray[0] to it, thereby making
myArray[1] point somewhere inside the 1st myStruct and messing up
everything?


Neither. It won't compile. Try it and see.

What you want, in essence, is to allocate some memory for each of
the pointers to point to. You want

myArray[0] = malloc(sizeof *myArray[0]);
myArray[1] = malloc(sizeof *myArray[0]);
myArray[2] = malloc(sizeof *myArray[0]);
myArray[3] = malloc(sizeof *myArray[0]);
...
myArray[9] = malloc(sizeof *myArray[0]);
Now, you can of course put that inside a loop:

for (i=0; i < 10; ++i)
myArray[i] = malloc(sizeof *myArray[i]);

...
for (i=0; i < 10; ++i) /* free each block */
free(myArray[i]);
Or you can merge all the memory allocations into one big chunk:

myArray[0] = malloc(10 * sizeof *myArray[0]);
for (i=0; i < 10; ++i)
myArray[i] = myArray[0] + i;

...
free(myArray[0]); /* free the big chunk directly */
The first way is easier IMHO; the second, big-chunk way may
be more efficient if you are doing a lot of memory allocation.

Oh, and about 'calloc': As a general rule, don't use it for
structs. Don't use it for anything, really, because it often
doesn't do anything more useful than 'malloc'.
'calloc' zeroes out all the bits in the allocated chunk of
memory. This makes it good for initializing 'unsigned char's,
but that's just about all. All-bits-zero is *not* guaranteed
to be anything useful with respect to pointers, floating-point
numbers, or even regular old integers(!). So 'calloc' isn't
very useful. Use 'malloc' instead.

HTH,
-Arthur
Nov 13 '05 #2
Koster wrote:
I have a question about the appropriateness of calloc. Consider an array of
pointers to structs which need to be allocated space on the heap, for example:
The standard C language has no notion of heap (which gives too much
detail about implementation details). It speaks of allocated storage
duration. As I said, this can be implemented as a heap, but it is not
guaranted nor necessary.
typedef struct myStruct *PMYSTRUCT;
It is usually not a good idea to hide that a type is actually a pointer
type. I would rather advise, for example, and notwithstanding the
invasion of the POSIX reserved namespace:

typedef struct myStruct myStruct_t;
struct myStruct
{
int i;
int j;
...etc... }; /* <-- note the required ; */
PMYSTRUCT myArray[10];
myStruct_t *myArray[10];
While I know I can point and allocate each element manually my looping mallocs,
I wonder if calloc will do what I want. Will executing "myArray = calloc(10,
sizeof(myStruct));" allocate 10 myStructs somewhere on the heap and put pointers
to each one in the myArray array, or will it allocate the myStructs and point
myArray[0] to it, thereby making myArray[1] point somewhere inside the 1st
myStruct and messing up everything?
Second option. malloc and calloc behave essentially the same, with one
exception. The standard says:

7.20.3.1 The calloc function
Synopsis
1 #include <stdlib.h>
void *calloc(size_t nmemb, size_t size);
Description
2 The calloc function allocates space for an array of nmemb objects,
each of whose size is size. The space is initialized to all bits
zero. 252)

And note 252 says:

252) Note that this need not be the same as the representation of
floating-point zero or a null pointer constant.

On the other hand, for malloc, we have:

7.20.3.3 The malloc function
Synopsis
1 #include <stdlib.h>
void *malloc(size_t size);
Description
2 The malloc function allocates space for an object whose size is
specified by size and whose value is indeterminate.

So the only difference between malloc and calloc (besides the argument
format) is that calloc also initializes the storage to all bits 0. Given
note 252, this is not even very useful, so that in practice you have
almost no reason to use calloc...
I hope that's clear enough,


Same here :-)

--
Bertrand Mollinier Toublet
"No sea vivo, Buendia" -- El presidente del tribunal,
in Cien anos de soledad, de Gabriel Garcia Marquez

Nov 13 '05 #3
Koster <ko***********@yahoo.com.sg> wrote:
I have a question about the appropriateness of calloc. Consider an array of
pointers to structs which need to be allocated space on the heap, for example:
Where the system will allocate space for you shouldn't be of any
concern for you as long as you're writing portable C;-)
typedef struct myStruct *PMYSTRUCT;
struct myStruct
{
int i;
int j;
...etc...
} PMYSTRUCT myArray[10]; While I know I can point and allocate each element manually my looping mallocs,
I wonder if calloc will do what I want. Will executing "myArray = calloc(10,
sizeof(myStruct));" allocate 10 myStructs somewhere on the heap and put pointers
to each one in the myArray array, or will it allocate the myStructs and point
myArray[0] to it, thereby making myArray[1] point somewhere inside the 1st
myStruct and messing up everything?


First of all, since you has made PMYSTRUCT to be a *pointer* to
struct myStruct, the line

PMYSTRUCT myArray[10];

will give you an array of ten such *pointers*. It's as if you had written

struct myStruct *myArray[ 10 ];

When you then try to do an assignment as in

myArray = calloc( 10, sizeof( myStruct ) );

your compiler should complain loudly because your 'myArray' can't be
used unadorned as a left hand side value - only when used on the right
hand side or as part of an expression it decays into a pointer to the
first element of the array. So you need either

*myArray = calloc( 10, sizeof( myStruct ) );

or, equivalently,

myArray[ 0 ] = calloc( 10, sizeof( myStruct ) );

to assign to the first element of the array 'myArray'. Of course, when
you do this all the other nine elements will still point to some random
places in memory.

You have two alternatives. First, change the typedef to

typedef struct myStruct PMYSTRUCT;

so that PMYSTRUCT does not translate to a pointer to a myStruct
structures but to 'struct myStruct' itself. Then

PMYSTRUCT myArray[10];

will give you an array of 10 such structures with all memory already
attached, so you don't have to use calloc() or malloc().

Or, if you insist on

typedef struct myStruct *PMYSTRUCT;

use

PMYSTRUCT myArray;

(But then I still would prefer

typeded struct myStruct MYSTRUCT;
MYSTRUCT *myArray;

so you always know if you're dealing with a real structure or a pointer,
instead of having the "pointerness" of it hidden, which in my opinion
makes reading code much more difficult). Then you can allocate memory
with

myArray = calloc( 10, sizeof *myArray );

and you now can treat myArray basically like an array of 10 strutctures,
i.e. you can get at the member 'i' of the 5th structure with
'myArray[ 4 ].i' etc.
Regards, Jens
--
_ _____ _____
| ||_ _||_ _| Je***********@physik.fu-berlin.de
_ | | | | | |
| |_| | | | | | http://www.physik.fu-berlin.de/~toerring
\___/ens|_|homs|_|oerring
Nov 13 '05 #4
On Thu, 11 Sep 2003, Arthur J. O'Dwyer wrote:
'calloc' zeroes out all the bits in the allocated chunk of
memory. This makes it good for initializing 'unsigned char's,
but that's just about all.


Just about. AAMOF, any character type will work (and as Jack Klein
pointed out recently, so will C99's intN_t and uintN_t types).

--
au***@axis.com
Nov 13 '05 #5
On 11 Sep 2003 15:33:00 GMT, Je***********@physik.fu-berlin.de wrote:

|Koster <ko***********@yahoo.com.sg> wrote:
|> I have a question about the appropriateness of calloc. Consider an array of
|> pointers to structs which need to be allocated space on the heap, for example:
|
|Where the system will allocate space for you shouldn't be of any
|concern for you as long as you're writing portable C;-)

Okay, forget the part about the heap. It's irrelevant anyway.

|> typedef struct myStruct *PMYSTRUCT;
|> struct myStruct
|> {
|> int i;
|> int j;
|> ...etc...
|> }
|
|> PMYSTRUCT myArray[10];
|

<snip>

|
|First of all, since you has made PMYSTRUCT to be a *pointer* to
|struct myStruct, the line
|
|PMYSTRUCT myArray[10];
|
|will give you an array of ten such *pointers*. It's as if you had written
|
|struct myStruct *myArray[ 10 ];

That is correct. I'm using an array of pointers to implement a hashtable. I do
not want an array of structs because the number of elements is highly volatile,
and as such I put them in a linked list rather than an array.

|When you then try to do an assignment as in
|
|myArray = calloc( 10, sizeof( myStruct ) );
|
|your compiler should complain loudly because your 'myArray' can't be
|used unadorned as a left hand side value - only when used on the right
|hand side or as part of an expression it decays into a pointer to the
|first element of the array. So you need either

Interestingly then, the MS VC++ compiler compiles the above line without any
problems, although admittedly with a cast to my pointer-to-myStruct typedef. I
see now (and I guess I'm an ass for not noticing it earlier), that it made all
the extensions .cpp for me, and as such it probably accepts a lot of my errors.
I have renamed them all to .c and sure enough it comes up with >60 build errors.

Whoops. It's a hobby project anyway, I can afford to waste time fixing it up :)

|*myArray = calloc( 10, sizeof( myStruct ) );
|
|or, equivalently,
|
|myArray[ 0 ] = calloc( 10, sizeof( myStruct ) );
|
|to assign to the first element of the array 'myArray'. Of course, when
|you do this all the other nine elements will still point to some random
|places in memory.

That's what I needed to know :)
So to allocate a struct for each element in the array to point to, I should just
loop through each and malloc each one individually, storing the returned pointer
in the appropriate array element, and forget about calloc.

<snip>

Thanks,
Koster.

Nov 13 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

29
by: David Hill | last post by:
Is there a difference between: /* code 1 */ struct sample test; test = malloc(sizeof(struct sample)); memset(&test, 0, sizeof(test)); /* code 2 */ struct sample test; test = calloc(1,...
26
by: dagger | last post by:
Hi there. I'm using C under FreeBSD with the gcc compiler and am having a bit of trouble using the calloc and realloc calls. As an example the code snippet: #include <stdio.h> int main() {...
16
by: laberth | last post by:
I've got a segmentation fault on a calloc and I don'tunderstand why? Here is what I use : typedef struct noeud { int val; struct noeud *fgauche; struct noeud *fdroit; } *arbre; //for those...
37
by: Harsimran | last post by:
Can any one explain what are far pointers and what is the difference between malloc and calloc .Which is better ?
40
by: boris | last post by:
Hi! I'm seeking some answers about what seems to be a memory leak. I have a loop that looks much like this: double *largeArray = (double*) calloc(); for (...) { printf("iteration #...\n");...
11
by: lohith.matad | last post by:
Hi all, Though the purpose of both malloc() and calloc() is the same, and as we also know that calloc() initializes the alloacted locations to 'zero', and also that malloc() is used for bytes...
2
by: chingfulan | last post by:
I have the following code and I can not figure out why Stg2In returns a null pointer? "Stg2In = (float *)calloc(9*DataLen, sizeof(float)); " while "Stg2Out = (float *)calloc(9*DataLen,...
8
by: venkatesh | last post by:
hai to everybody, i am having doubt in difference between the malloc and calloc function. please tell where to use and when to use those functions?
14
by: Roka100 | last post by:
Hi all, I tried 2 programs : #include <stdio.h> #include <string.h> 1, int main(void){ char *str = NULL;
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.