C function malloc() does not work as I expected [duplicate] - c

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.

Related

Why am I not getting the correct size after using malloc and printing using sizeof?

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.

How to get the size of dynamically allocated 2d array

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.

Confused with results of sizeof() function

I'm trying to write a function that converts a base 10 integer to a binary number.
I am constructing the function like this:
void dec2bin(int dec, char * bin);
The function will store the binary result by means of the pointer in the argument. It is passed a variable declared elsewhere as follows:
char *r1 = (char *)malloc(24);
The first thing the function has to do is fill the "24 bit result" with all zeros. It works great now since I've coded it based on me knowing the "size," but I can't figure out how to determine the "size" of an arbitrary "r1". Every way I can think to use the sizeof function does not give me 24.
I am confused at this point, and not connecting the relationship between the respective sizes of a char, char*, etc and how I can use those sizes to get what I'm looking for with respect to "r1".
Would someone mind giving me a pointer? Pun intended.
Thanks!
You may just pass the size as another parameter:
void dec2bin(int dec, char * bin, size_t max_chars);
I can't figure out how to determine the "size" of an arbitrary "r1".
You cannot do that: the information about the size that you passed to malloc is irreversibly lost after the call. All you have at that point is a pointer to the chunk of at least 24 bytes of memory. If you need the size, you need to store it somewhere else - for example, in a separate variable that you carry around.
Two typical work-arounds to this issue include (1) storing a zero-terminated string in the allocated space, and using the length of that string as the proxy to the size of the allocated chunk, and (2) defining your own structure that contains both the size and the allocated pointer. Neither solution is ideal, but at least the choice is with you.
The type of r1 is a char* (char pointer), so, like all pointers, its size is 4 (or 8, depending on your situation). No matter the size of the memory block you're allocating to it.
You can't retrieve the size of the allocated block from a pointer, so if you need the size later, you will have to remember the size yoursef (e.g. by storing it in a different variable).
r1 is a variable of pointer type, and its size is fixed and always the same (just like the size of any variable of a given type), which is no larger than (and usually equal to) sizeof(void *). What you really want to know is the size of the array that's sitting at *r1 (note the asterisk), and that is something you cannot know. You have to keep track of it yourself, typically like this:
size_t const n = get_some_number();
foo * p = calloc(n, sizeof(foo));
Now you use the pair (p, n) to describe your dynamic array.
(Note that C99 and C11 have the notion of a variable-length array, in whose context sizeof does actually (sometimes) give you the actual array size, but that's a somewhat murky affair, and in any case it isn't what you asked for.)
When you allocate memory, you get back a pointer, which has a fixed size, so there's no way to get the size of the allocated memory with sizeof.
As others have said, if it's just a pointer, you won't be able to tell anything (unless it's zero-terminated, in which case you can just iterate until you hit an element equal to zero (not the character '0')).
However, if you set it up as follows, you can actually see the buffer size after calling sizeof()... at least until you send it to a function, where the array decays to a plain char* pointer.
void test( char* s )
{
int i2 = sizeof( s ) / sizeof( char );
}
char c1[] = "Testing!";
int i1 = sizeof( c1 ) / sizeof( char ); // i1 is 9 (size of buffer)
test( c1 ); // i2 is 4 (size of pointer)

C dynamic memory allocation and sizeof()

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];

Why does my homespun sizeof operator need a char* cast?

Below is the program to find the size of a structure without using sizeof operator:
struct MyStruct
{
int i;
int j;
};
int main()
{
struct MyStruct *p=0;
int size = ((char*)(p+1))-((char*)p);
printf("\nSIZE : [%d]\nSIZE : [%d]\n", size);
return 0;
}
Why is typecasting to char * required?
If I don't use the char* pointer, the output is 1 - why?
Because pointer arithmetic works in units of the type pointed to. For example:
int* p_num = malloc(10 * sizeof(int));
int* p_num2 = p_num + 5;
Here, p_num2 does not point five bytes beyond p_num, it points five integers beyond p_num. If on your machine an integer is four bytes wide, the address stored in p_num2 will be twenty bytes beyond that stored in p_num. The reason for this is mainly so that pointers can be indexed like arrays. p_num[5] is exactly equivalent to *(p_num + 5), so it wouldn't make sense for pointer arithmetic to always work in bytes, otherwise p_num[5] would give you some data that started in the middle of the second integer, rather than giving you the sixth integer as you would expect.
In order to move a specific number of bytes beyond a pointer, you need to cast the pointer to point to a type that is guaranteed to be exactly 1 byte wide (a char).
Also, you have an error here:
printf("\nSIZE : [%d]\nSIZE : [%d]\n", size);
You have two format specifiers but only one argument after the format string.
If I don't use the char* pointer, the output is 1 - WHY?
Because operator- obeys the same pointer arithmetic rules that operator+ does. You incremented the sizeof(MyStruct) when you added one to the pointer, but without the cast you are dividing the byte difference by sizeof(MyStruct) in the operator- for pointers.
Why not use the built in sizeof() operator?
Because you want the size of your struct in bytes. And pointer arithmetics implicitly uses type sizes.
int* p;
p + 5; // this is implicitly p + 5 * sizeof(int)
By casting to char* you circumvent this behavior.
Pointer arithmetic is defined in terms of the size of the type of the pointer. This is what allows (for example) the equivalence between pointer arithmetic and array subscripting -- *(ptr+n) is equivalent to ptr[n]. When you subtract two pointers, you get the difference as the number of items they're pointing at. The cast to pointer to char means that it tells you the number of chars between those addresses. Since C makes char and byte essentially equivalent (i.e. a byte is the storage necessary for one char) that's also the number of bytes occupied by the first item.

Resources