tags:

views:

206

answers:

4

Hi...i have a text file where the first number defines the size of the arrays. I know that calloc or malloc can reserve memory, but how?

this code:

typedef struct alpha {
    int* size;
    char name;
    int  tot;
    char line[60];
} ALPHA;

fgets(line, 60, fp);
tot = atoi(line);
size = (int*)calloc(name, sizeof(int);

Imagine that in the first line of text is the number 10, with this code the size of name will be 10? like name[10]???

+3  A: 

Use one of the following:

ALPHA* alphas1 = calloc(tot, sizeof(ALPHA));
// or
ALPHA* alphas2 = malloc(tot * sizeof(ALPHA));

Those allocate memory for tot of your ALPHA structures.

Georg Fritzsche
You might need to cast the return value to (ALPHA *) to avoid compiler warnings.
Tyler
The question is tagged C. I would be annoyed by a C compiler that gives me a warning for THIS.
Secure
@Tyler, the only reason to cast the return value of malloc() / calloc() is to be compatible with C++.
Tim Post
@Tyler that's only needed in C++, in C it's recommended not to cast, as it makes the code less readable, and prone to errors.
Andrei Ciobanu
Oh cool. I wasn't aware of that.
Tyler
+1  A: 

You might just want to

ALPHA alphas[tot];

Jared P
I think his assignment requires the use of dynamic allocation.
Tim Post
Not to mention that should be `struct alpha alphas[tot];` or `ALPHA alphas[tot];`.
David Thornley
yup my bad - changed to ALPHAalso, this is dynamic allocation -- just on the stack instead of the heap, just like if I had used alloca
Jared P
A: 
ALPHA *alphas1 = calloc(tot, sizeof(*alphas1));
ALPHA *alphas2 = malloc(tot * sizeof(*alphas2));

is a slightly better version of:

ALPHA* alphas1 = calloc(tot, sizeof(ALPHA));
ALPHA* alphas2 = malloc(tot * sizeof(ALPHA));

Now you can access alphas1 and so on, "array-like":

alphas1[0], alphas1[1], alphas1[2], ..., alphas1[tot] 
alphas2[0], alphas2[1], alphas2[2], ..., alphas2[tot] 

alphas1[...] is of type ALPHA
alphas2[...] is of type ALPHA .

PS: To make your code more reliable, don't forget to check if a malloc / calloc failed. To this verify that (in your case) check if alphas1 or alphas2 are different from NULL. In case they are NULL, you won't be able to access them as presented, and you should design a mechanism to recover from this, or simply exit the program (+error message).

Andrei Ciobanu
+2  A: 

There's several problems with your code.

First, you seem to be confusing a declaration of what a data type is with actually having a variable. You declare a struct, and from then on it's a data type, much like int or double. Before you assign anything to one, you need to have one. You can get one either by defining one in the function (ALPHA a;) or by allocating memory for one with malloc() or calloc().

To use calloc(), you have two arguments, one being how many whatevers you want, and one being the size of a whatever. For malloc(), you multiply the two. The other difference is that malloc() returns memory with whatever used to be in it, while calloc() initializes everything to zero. (That's zero-length string or integral zeros according to the Standard. Other values are not guaranteed, but with most modern systems you'll get the equivalent of a zero.) These functions return a pointer to the memory allocated.

You seem to want tot ints, so (using calloc()), the correct statement is something like int * a = calloc(tot, sizeof(int));, or int * a = calloc(tot, sizeof(*a));. No cast is required in C (it is required in C++, but you usually wouldn't use malloc() or calloc() in C++), and the only thing it can do is cover up a possible mistake (leaving out #include <stdlib.h> to be specific).

Once you have that, you can refer to the ints as something like a[3].

Putting the result in a field of an ALPHA is doable, but you really do need an ALPHA, so something like

ALPHA a;
a.size = calloc(tot, sizeof(*a));

will work. You would therefore refer to it as a.size[3], for example.

Also, I don't see what name is doing. It's one character, which is not enough for any non-empty string, and I don't know why you've got it in the calloc() call. You might want name to be a dynamically allocated string, with size being its size. In that case, you'd need to change the lines in the declaration of ALPHA to be

int size;
char * name;

and the code might be be

ALPHA a;
fgets(line, 60, fp);
a.size = atoi(line);
a.name = calloc(a.size, sizeof(*a.name));

Once you've done that, after entering 10, you can refer to a.name[0] through a.name[9], and that's your ten characters. a.name[10] would be one past the end. Note that you can only put a nine-character string in a ten-character array, since you need to have room for the null terminator (the '\0' which is the last character of any C-style string). If you want to be able to enter the specified number of characters, you'd want to add 1 to a.size after putting the user-entered number in.

David Thornley