I have the doubt if calloc initialize to zero all of the elements of a struct array like:
#define MAXDATA 10
struct Est2 {
int dato0; // Index k
int dato1; // Index j
int dato2; // Index i
double dato3; // Y Coordinate
};
Est2 *myArray = (Est2*) calloc(MAXDATA, sizeof(Est2));
I'm asking this because I don't want the initial data of myArray have garbage or Is there a problem if I don't initialize the array with any value if later in the code I will initialize it anyway for example storing the result of some arithmetical operations? Thanks in advance.
From man calloc:
void *calloc(size_t count, size_t size);
The calloc() function contiguously allocates enough space for count objects that are size bytes of memory each and returns a pointer to the allocated memory. The allocated memory is filled with bytes of value zero.
calloc() guarantees that it's going to be pointing at zeroed data.
All of the bytes in the structure are set to 0.
This means that the ints have value 0. The double could be a trap , although most common systems use IEEE 754 representation for double, in which the value would be 0.0.
Related
I am learning C programming and this is my first course in programming. I am having some trouble with this snippet of code:
int* intArray;
intArray=(int*)malloc(5*sizeof(int));
I believe the number of elements in the array is 5 integers. However, what I don't really understand is the malloc function. Does it allocate enough memory for the addresses of 5 integers in this case?
Malloc returns a void pointer to the allocated space, or NULL if there is insufficient memory available. The parameter is the size, in bytes, to be allocated. So in the line intArray = (int*)malloc(5*sizeof(int)); you are requesting the allocation of memory sufficient for 5 ints (sizeof(int) gives the size of an int type). (malloc)
Using malloc requests the allocation of memory sufficient for 5 new integers.
No, the malloc allocates enough memory for 5 integers. It allocates what is passed into the function: 5*sizeof(int). What might be confusing you is that intArray is a pointer allocated on the stack, which points to the memory address of the beginning of the malloc'ed memory.
If you want memory for addresses of 5 integers, you would do something like:
int** intArray;
intArray=(int**)malloc(5*sizeof(int*));
The malloc function allocates the number of bytes you request in the argument and returns the address in memory of the beginning of the block. In this case you have requested a block of memory large enough to hold 5 integer values.
You cast it to an int * so the compiler will handle the address as containing integers when indexing and dereferencing.
Malloc function call as you observe requires a value specifying number of bytes. From the documentation on malloc:
void* malloc (size_t size);
Allocate memory block. Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.
The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.
Hence, in your code snippet:
intArray=(int*)malloc(5*sizeof(int));
int size is 2 bytes. sizeof(int) returns 2. Hence 5 * sizeof(int) = 10. So, code resolves to intArray = (int*)malloc(10);
I have dynamically allocated 2D array.
Here is the code
int **arrofptr ;
arrofptr = (int **)malloc(sizeof(int *) * 2);
arrofptr[0] = (int *)malloc(sizeof(int)*6144);
arrofptr[1] = (int *)malloc(sizeof(int)*4800);
Now i have to know that how many bytes are allocated in arrofptr,arrofptr[0],arrofptr[1]?
is there any way to know the size?
if we will print
sizeof(arrofptr);
sizeof(arrofptr[0]);
sizeof(arrofptr[1]);
then it will print 4.
You can't find size of arrofptr, because it is only a pointer to pointer. You are defining an array of arrays using that. There's no way to tell the size information with only a pointer, you need to maintain the size information yourself.
The only return value you get from malloc() is a pointer to the first byte of the allocated region (or NULL on failure). There is no portable, standard, way of getting the associated allocation size from such a pointer, so in general the answer is no.
The C way is to represent arrays and buffers in general with a pair of values: a base address and a size. The latter is typically of the type size_t, the same as the argument to malloc(), by the way.
if you want to keep track of the size of an allocated block of code you would need to store that information in the memory block that you allocate e.g.
// allocate 1000 ints plus one int to store size
int* p = malloc(1000*sizeof(int) + sizeof(int));
*p = (int)(1000*sizeof(int));
p += sizeof(int);
...
void foo(int *p)
{
if (p)
{
--p;
printf( "p size is %d bytes", *p );
}
}
alt. put in a struct
struct
{
int size;
int *array;
} s;
You can't get the length of dynamically allocated arrays in C (2D or otherwise). If you need that information save it to a variable (or at least a way to calculate it) when the memory is initially allocated and pass the pointer to the memory and the size of the memory around together.
In your test case above sizeof is returning the size of the pointer, and thus your calculation the size of the pointers is usually 4, this is why you got 4 and is likely to have the trivial result of 4, always.
#include <stdio.h>
#include <stdlib.h>
#define MAX 10
void main()
{
int *ptr, *arr[MAX];
int i, j;
for (i=MAX-1; i>=0; i--)
if (arr[i]=(int*)malloc(i*sizeof(int))) // <= that line!
for (j=0; j<i; j++)
*(*(arr+i)+j) = j*i;
ptr = *(arr+MAX-1);
while (*ptr)
printf ("%d ", *ptr--);
}
I am not understand what the purpose of this command:
arr[i]=(int*)malloc(i*sizeof(int))
I know that this malloc dynamic allocation.
But what is meant by arr[i] it gives the sizeof*i ?
Thanks.
The command that you are talking about allocates a block of length that is sufficient to store i items of type int, and stores the result at the i-th position in the array of pointers called arr. The program creates a "triangular" arr array: its elements are arrays of different lengths, arranged in such an order that arr[i] can hold i elements.
By the way, this code is missing calls to free for the items it has allocated.
int *ptr, *arr[MAX]
creates a pointer to int and an array with MAX elements of pointers to int.
arr[i]=(int*)malloc(i*sizeof(int))
Allocates space for i ints for every int pointer.
At first sizeof() "returns" (it should be replaced with numeric value during compilation) the size of provided type. Means 4 for int (8 on 64b machines), 1 for char and so on.
Therefore i*sizeof(int) means size for i ints (i = 4; sizeof( int) = 4; than it's 16).
malloc() uses number of bytes to allocate as parameter, therefore malloc(16) allocate 16bytes, enough space for 4 4B integers.
(int*) is just something like C-hack to have correct types (because you want to use those 16B as int[4] not as void *).
The whole code means to allocate space for i ints on i-th place of array (1 on first, 2 on second...). However I wander what will happen for 0, when you'll try to allocate 0 Bytes :)
It's allocating increasingly longer arrays as each element of the arr. so arr[0] points to a 0 size array, arr[2] points to an array of 2 ints and so on.
arr is an array of pointers to int. Every element of it - arr[x] - is a pointer to int, so an array. It's an array of arrays of ints.
For each element of the array, you create an array with size of the current index.
Note though that your code is illegal, since when i==0, you will call malloc(0).
Also, it's good practice not to cast the return type of malloc.
I created a dynamic array ,and i need to initialize all the members to 0.
How can this be done in C?
int* array;
array = (int*) malloc(n*sizeof(int));
In this case you would use calloc():
array = (int*) calloc(n, sizeof(int));
It's safe to assume that all systems now have all zero bits as the representation for zero.
ยง6.2.6.2 guarantees this to work:
For any integer type, the object representation where all the bits are
zero shall be a representation of the value zero in that type.
It's also possible to do a combination of malloc() + memset(), but for reasons discussed in the comments of this answer, it is likely to be more efficient to use calloc().
memset(array, 0, n*sizeof(int));
Or alternatively, you could allocate your block of memory using calloc, which does this for you:
array = calloc(n, sizeof(int));
calloc documentation:
void *calloc(size_t nmemb, size_t size);
The calloc() function allocates memory for an array of nmemb elements of size bytes each and returns a pointer to the allocated memory. The memory is set to zero. ...
Use calloc function (usage example):
int *array = calloc(n, sizeof(int));
From calloc reference page:
void *calloc(size_t nelem, size_t elsize);
The calloc() function shall allocate unused space for an array of nelem elements each of whose size in bytes is elsize. The space shall be initialized to all bits 0.
memset(array, 0, n * sizeof *array);
for (i=0; i<x; ++i){
array[i]=0;
}
That should do the trick. I guess you have to make a loop that makes 0 every element in the array. Memset could also work for you.
I'm having some trouble understanding the difference between these two code segments:
I allocate space for an array of integers dynamically within my code with the following statement
int *arr = calloc(cnt, sizeof(int));
In another function, where I pass in arr, I would like to determine the size (number of elements) in arr.
When I call
int arr_sz = sizeof(arr)/sizeof(int);
it only returns 1, which is just the number of bytes in an int for both arguments I am assuming (4/4)=1.
I just assumed it would be the same as using an array
int arr[8];
int arr_sz = sizeof(arr)/sizeof(int);
which returns the actual number of elements in the array.
If anyone could clear this up, that would be great. Thanks!
int *arr; ----> Pointer
int arr[8]; ----> Array
First up what you got there - int *arr is a pointer, pointing to some bytes of memory location, not an array.
The type of an Array and a Pointer is not the same.
In another function where I pass in arr, I would like to determine the size (number elements) in arr. When I call
int arr_sz = sizeof(arr)/sizeof(int);
it only returns 1, which is just the number of bytes in an int for both arguments I am assuming (4/4)=1. I just assumed it would be the same as using an array
Even if it is assumed to be an Array -- that's because Arrays get decayed into pointers when passed into functions. You need to explicitly pass the array size in functions as a separate argument.
Go through this:
Sizeof an array in the C programming language?
There is a difference between a static array and dynamic memory allocation.
The sizeof operator will not work on dynamic allocations.
AFAIK it works best with stack-based and predefined types.
well, int *arr declares a pointer, a variable which keeps the address of some other variable, and its size is the size of an integer because it's a pointer, it just have to keep the address, not the pointee itself.
int arr[8] declares an array, a collection of integers. sizeof(arr) refers to the size of the entire collection, so 8*sizeof(int).
Often you hear that "array and pointers are the same things". That's not true! They're different things.
Mike,
arr is a pointer and as such, on your system at least, has the same number of bytes as int. Array's are not always the same as pointers to the array type.
sizeof(arr) is the same as sizeof(int*), i.e. the size of a single pointer. You can however calculate arr_sz as ... cnt!
*arr is not the same as arr[8] since it's size is not known in compile time, and sizeof is a function of the compiler. So when your arr is *arr sizeof will return the size of the pointer (sizeof(int *))in bytes, while when your arr is arr[8], the sizeof will return the size of array of 8 integers in bytes (which is sizeof(int) * 8).
When you pass a pointer to array to a function, you must specify its size, because the compiler can't do it for you. Another way is to end the array with null element, and perform a while loop.
If you have int arr1[8] the type of arr1 (as far as the compiler is concerned) is an array ints of size 8.
In the example int * arr2 the type of arr2 is pointer to an integer.
sizeof(arr1) is the size of an int array
sizeof(arr2) is the size of an int pointer (4 bytes on a 32 bit system, 8 bytes on a 64 bit system)
So, the only difference is the type which the compiler thinks that variable is.
You can't use sizeof with memory pointers:
int *arr = calloc(cnt, sizeof(int));
But it's ok to use it with arrays:
int arr[8];