I was trying to understand some code written by others. But I am not very familiar with C. Could anyone explain the following code? Thx ahead!
struct cell *ptr = (struct cell* ) malloc ( (input * 1024) * sizeof(struct cell));
This code creates a pointer of type struct cell named ptr which points to a memory location- a sequence of (input*1024) number of blocks, where each block is of size sizeof(struct cell)
This is dynamic memory allocation. During runtime if there is not that much amount of free memory, it will return NULL and ptr will be pointing to NULL It always advised to check ptr for NULL value before playing with it.
As you have allocated the memory dynamically, it's your responsibility to free/reclaim it by calling free(ptr) once you are done.
This was a way of allocating memory in the 1970s which is still sometimes seen today, perhaps due to a "cargo cult" programming mentality.
The effect is to allocate a contiguous array which has 1024 * input number of elements, and each element is an (uninitialized) struct cell.
Today we would write:
struct cell *ptr = malloc( input * 1024 * sizeof *ptr );
or
struct cell *ptr = calloc( input * 1024, sizeof *ptr );
The latter will also initialize any integers in the struct to have value 0, and any char arrays to contain empty strings; and may be faster depending on the operating system.
The sizeof *ptr part is necessary because the malloc family of functions expect number of bytes instead of number of elements so we must multiply by the number of bytes per element; and if ptr points to an element, then *ptr is an element, so sizeof *ptr retrieves the size of that element.
For explanation of why the old style is no longer in favour, see here.
This code dynamically allocates a number of struct cell's. The number is equal to input*1024. As a result ptr will be a 1D array of structs. Don't forget to free() it!
Also say to these others not to cast malloc().
The function malloc is used to dynamically allocate memory, it is used when you have no prior knowledge of how large something will be beforehand. Its argument is the number of bytes you want. Given an input, in this case input, it will give you that number of struct cells times 1024. Think of it like a matrix, where 1024 is the width and input is the height. Finally the function returns the pointer to the allocated memory block which is stored in ptr so that you can use it.In a object oriented language it is the equivalent of creating an array of objects, the size of the "object" is the size of the cell, input would be the number of such "arrays of objects" you are creating, and 1024 is the array length.
Related
This is my code.
#include<stdio.h>
typedef struct {
int a,b;
} integers;
void main() {
integers *ptr = (integers *)malloc(10*sizeof(integers));
printf("%d",sizeof(*ptr)); // prints 8
}
From what I understand about Malloc, the above code should actually reserve 10x8=80 bytes of memory for ptr to point to.
Why then does using sizeof(*ptr) give only 8? How do I find the total size being allocated for ptr?
Because you're using sizeof(*ptr) you're actually asking for the size of the first element in the allocated buffer, thus sizeof will return the size of the first element in ptr (i.e. 2x4 bytes integers on 32bits system) rather than the allocated size.
Also, please note that even if you'd use sizeof(ptr) you'd get the size of the ptr pointer which on 32bits system would be 4 bytes.
Well, I know that this question is pretty outdated but finding no suitable answer, I decided to write one.
When specifying sizeof(*ptr), you're actually trying to reach out for the size of data type you've stored in the variable that the pointer is pointing to( here its the first element of the array). Here, that's quite evidently 8.
Even when you'll try to print sizeof(ptr), you'll be again printing the size of the pointer address which by default is 8 bytes in GCC compilers as the data type is long unsigned int.
Why then does using sizeof(*ptr) give only 8? How do I find the total size being allocated for ptr?
The type of the expression *ptr is integers - thus,
sizeof *ptr == sizeof (integers) == sizeof (int) + sizeof (int)
You cannot determine the size of the allocated buffer by looking at the pointer (it doesn't store any metadata about the buffer size). You will have to keep track of that information separately.
Edit
Note that you can do something like the following:
integers (*foo)[10] = malloc( sizeof *foo );
if ( foo )
printf( "sizeof *foo = %zu\n", sizeof *foo );
and that will give you the result you're expecting. In this case, foo is a pointer to an array of integers, not to a single instance of integers, so sizeof *foo will give you the size of the allocated array. The downside is that you have to expliticly dereference foo before applying the subscript:
(*foo)[i].a = some_value(); // or foo[0][i].a
(*foo)[i].b = some_other_value(); // or foo[0][i].b
This is normally done when you want to allocate an NxM array and make sure all the rows are contiguous:
integers (*foo)[10] = malloc( 10 * sizeof *foo );
will allocate a 10x10 array of integers such that the rows are all adjacent in memory.
Also, a pointer to a 10-element array of integers is not compatible with a pointer to an 11-element array of integers, making it more difficult to write functions that can work with pointers to arrays of different sizes. IOW, if you have a function declared as
void bar( integers (*foo)[10] ) { ... }
it can only work with Nx10 arrays of integers. There are ways around this that involve varying levels of pain, but that's a topic for another day.
This is my code.
#include<stdio.h>
typedef struct {
int a,b;
} integers;
void main() {
integers *ptr = (integers *)malloc(10*sizeof(integers));
printf("%d",sizeof(*ptr)); // prints 8
}
From what I understand about Malloc, the above code should actually reserve 10x8=80 bytes of memory for ptr to point to.
Why then does using sizeof(*ptr) give only 8? How do I find the total size being allocated for ptr?
Because you're using sizeof(*ptr) you're actually asking for the size of the first element in the allocated buffer, thus sizeof will return the size of the first element in ptr (i.e. 2x4 bytes integers on 32bits system) rather than the allocated size.
Also, please note that even if you'd use sizeof(ptr) you'd get the size of the ptr pointer which on 32bits system would be 4 bytes.
Well, I know that this question is pretty outdated but finding no suitable answer, I decided to write one.
When specifying sizeof(*ptr), you're actually trying to reach out for the size of data type you've stored in the variable that the pointer is pointing to( here its the first element of the array). Here, that's quite evidently 8.
Even when you'll try to print sizeof(ptr), you'll be again printing the size of the pointer address which by default is 8 bytes in GCC compilers as the data type is long unsigned int.
Why then does using sizeof(*ptr) give only 8? How do I find the total size being allocated for ptr?
The type of the expression *ptr is integers - thus,
sizeof *ptr == sizeof (integers) == sizeof (int) + sizeof (int)
You cannot determine the size of the allocated buffer by looking at the pointer (it doesn't store any metadata about the buffer size). You will have to keep track of that information separately.
Edit
Note that you can do something like the following:
integers (*foo)[10] = malloc( sizeof *foo );
if ( foo )
printf( "sizeof *foo = %zu\n", sizeof *foo );
and that will give you the result you're expecting. In this case, foo is a pointer to an array of integers, not to a single instance of integers, so sizeof *foo will give you the size of the allocated array. The downside is that you have to expliticly dereference foo before applying the subscript:
(*foo)[i].a = some_value(); // or foo[0][i].a
(*foo)[i].b = some_other_value(); // or foo[0][i].b
This is normally done when you want to allocate an NxM array and make sure all the rows are contiguous:
integers (*foo)[10] = malloc( 10 * sizeof *foo );
will allocate a 10x10 array of integers such that the rows are all adjacent in memory.
Also, a pointer to a 10-element array of integers is not compatible with a pointer to an 11-element array of integers, making it more difficult to write functions that can work with pointers to arrays of different sizes. IOW, if you have a function declared as
void bar( integers (*foo)[10] ) { ... }
it can only work with Nx10 arrays of integers. There are ways around this that involve varying levels of pain, but that's a topic for another day.
Is there any way to find the structure size dynamically in C??
Sizeof is compile time operator.. so what's the other option.
If we can have dynamically allocated array(flexible arrays) in a structure, then finding the structure size dynamically should also be there.. Plz help me out...
When you allocate an array dynamically in C, then you must remember its size too, if you wish to know the size of the array!
Structure sizes must be known at compile-time.
If it contains a pointer to dynamically allocated memory then that memory is not part of the struct - it's outside the struct and the pointer is pointing at it - so it does not affect the sizeof the struct.
If you're talking about flexible array member then you will need to implement your own way of knowing how much memory you allocated, e.g. have a struct member variable that holds the size.
sizeof's results are compile time constant as a the size of a variable or structure does not change during run-time.
The only exception to this are V(ariable)L(ength)Arrays for which the code defnding them "knows" the size.
Referring:
we can have dynamically allocated array in a structure
So let's assume:
struct s
{
size_t size;
int * ints;
}
The size is sizeof(struct s). That is the sum of
the size of an unsigned interger: sizeof(size_t)
the size of a pointer to int: sizeof (int *)
some optional padding bytes
This is independed of to how many bytes the structure's member int * ints may point.
I've read various tutorials on pointers, and I now come with a question,
is this:
char *input = malloc(sizeof(char)*24);
the same as
char *input[24];
I was under the impression that the malloc will also create my space on the heap with 24 slots. Usually, I see char input[24], but the char *input[24] I figured was a simpler way than mallocing.
Thanks!
No, they are not the same.
char *input = malloc(sizeof(char)*24);
will allocate a block of 24 char's on the heap and assign a pointer to the start of that block to input. (technically you are just telling it to allocate x number of bytes where x is 24 times the size, in bytes, of each char)
char *input[24];
will create an array of 24 char pointers on the stack. These pointers will not point to anything (or garbage on init) as you have it written.
For the second example, you could then take each pointer in the array input and allocate something for it to point to on the heap. Ex:
char *input[NUM_STRS];
for( int i = 0; i < NUM_STRS; i++ )
{
input[i] = malloc( MAX_STR_LEN * sizeof(char) );
}
Then you would have an array of character pointers on the stack. Each one of these pointers would point to a block of characters on the heap.
Keep in mind, however, that things on the stack will be popped off when the function exits and that variable goes out of scope. If you malloc something, that pointer will be valid until it is freed, but the same is not true of an array created on the stack.
EDIT:
Based on your comment, here is an example of making 24 character pointers on the heap and allocating space for them to point to:
#define NUM_STRS 24
#define MAX_STR_LEN 32
char **input = malloc( sizeof(char *) * NUM_STRS );
for( int i = 0; i < NUM_STRS; i++ )
{
input[i] = malloc( sizeof(char) * MAX_STR_LEN );
}
Please keep in mind that with this example you will have to free each pointer in input, and then input itself at the appropriate time to avoid leaking memory.
These are not the same at all.
char *input = malloc(sizeof(char)*24);
This allocates enough memory to hold 24 char, and assigns the address to input (a pointer). This memory is dynamically-allocated, so it needs to be released at some point with an appropriate call to free().
char *input[24];
This declares input to be an array of 24 pointers. This has automatic storage, which means you do not need to free it. (However, you may need to free the things being pointed to by each of the pointers, but that's a different matter!)
Fundamentally, the types of the two variables are different. In the first case, you declare a pointer to char that points to memory dynamically allocated by malloc (which you are morally obligated to free at a later instant). In the second case, you declare an array of pointers to char.
Couple of observations:
sizeof(char) is one by definition, so you can leave that out. (No, it does not convey a documenting purpose. You are better of rewriting it as char *input = malloc( 24 * sizeof *input );)
Very seldom will the call to malloc have an integer literal. If it does (24) in your example, then usually one would prefer to have an array to hold that (there are some considerations regarding stack usage that I am side-stepping here).
hope this helps,
You can compare it better to char input[24]; (note no *). With that you can use input in the same way but the memory is on the stack instead of on the heap.
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.