Why does the following code output 4 twice, instead of 8 and 20?
Thanks
int size = 0;
int *pointer;
pointer = malloc(2 * sizeof(int));
size = sizeof(pointer);
printf("%d", size);
int *temp = realloc(pointer, 5 * sizeof(int));
if (temp != NULL) //realloc was successful
{
pointer = temp;
} else //there was an error
{
free(pointer);
printf("Error allocating memory!\n");
}
size = sizeof(pointer);
printf("%d", size);
sizeof is a compile-time operator that tells you how much space a variable or a type takes up. The answer you get is a constant. In the case of a pointer, sizeof tells you how many bytes it takes to store a memory address. This is typically 4 bytes on a 32-bit platform and 8 bytes on a 64-bit one.
It does not tell you how much memory has been allocated by malloc(). As it turns out, there unfortunately is no standard function to tell you the size of an allocated memory block. You have to keep track of it yourself.
sizeof is evaluated at compile time, not run time (except in the case of variable length arrays, an odd feature of C99). In this case you're taking the size of the pointer, which is 4 bytes. Even if you took sizeof(*pointer), that would be equivalent to saying sizeof(int)
I realize you're trying to tell the size of the dynamically allocated memory, but there is no standard way to do this. You should just keep track of it yourself, in your own code.
Related
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
newbie questions about malloc and sizeof
I am trying to read strings into a program. When I noticed that the strings were sometimes being corrupted, I tried the following code:
void *mallocated = malloc(100);
printf("sizeof(mallocated) = %d\n", sizeof(mallocated));
According to my program, the size of mallocated was 8, even though I allocated 100 bytes for it. Because of this, whenever I try to store a string longer than 8 bytes, everything after the 8th byte will sometimes disappear. Why is this happening, and how can I prevent it?
Because the size of the "string" pointer is 8 bytes. Here are some examples of using sizeof() with their appropriate "size". The term size_of() is sometimes deceiving for people not used to using it. In your case, the size of the pointer is 8 bytes.. below is a representation on a typical 32-bit system.
sizeof (char) = 1
sizeof (double) = 8
sizeof (float) = 4
sizeof (int) = 4
sizeof (long) = 4
sizeof (long long) = 8
sizeof (short) = 2
sizeof (void *) = 4
sizeof (clock_t) = 4
sizeof (pid_t) = 4
sizeof (size_t) = 4
sizeof (ssize_t) = 4
sizeof (time_t) = 4
Source
You are leaving out how you are determining your string is disappearing (char array). It is probably being passed to a function, which you need to pass the explicit length as a variable or track it somewhere. Using sizeof() won't tell you this.
See my previous question about this and you'll see even my lack of initial understanding.
In C89, sizeof operator only finds the size of a variable in bytes at compile time (in this case a void pointer of 8 bytes). It works the way you'd expect it to work on plain arrays, because their size is known at compile time.
char arr[100]; // sizeof arr == 100
char *p = arr; // sizeof p == 4 (or 8 on 64-bit architectures)
char *p = malloc(100); // sizeof p == 4 (or 8). Still!
To know the size of heap-allocated memory, you need to keep track of it manually, sizeof won't help you.
sizeof returns the size of the pointer (void *) that you gave it, not the size of the memory you allocated. You would have to store the size of the memory in a separate variable if you want to use it later.
You cannot. As pointed out, you can get the size of the void * mallocated, but that does not tell you much.
You cannot get the size of the malloed *mallocated. That is to say, there is no function call to return 100 (in your example) - unless you write your own memory management routines.
Simplest is just to remember it somewhere ... maybe ....
stuct {
void *data;
unsigned int size
} myStructureWhichRemebersItsSize;
myStructureWhichRemebersItsSize *someData;
someData.data = malloc(100); // and check for NULL
someData.size = 100;
void* is the type of a location in memory if you don't know what it contains. It should be avoided.
char* is the type of a value which points to some location in memory which holds a char. Identifying a location in memory takes eight bytes.
sizeof tells you how many bytes a particular type takes. Not how many were allocated with malloc but just how much memory compiler knows the type should take. Applying sizeof to values is often considered bad style, and as someone else mentioned here, sometimes invokes smart behavior in C99.
char[100] the type of a value which holds 100 chars. char[100] a; is a string of 100 chars on the stack.
char(*)[100] is the type of a pointer to a value that holds 100 chars. char(*b)[100]; makes b point to 100 chars, possibly on the heap. What you probably want is
char (*s)[100] = malloc( sizeof( char[100] ) );
printf( "%u byte pointer to %u bytes of size %u elements\n",
sizeof s, sizeof *s, sizeof **s );
I have always used the malloc function as, for exemple,
int size = 10000;
int *a;
a = malloc(size * sizeof(int));
I recently run into a piece of code that discards the sizeof(int) part, i.e.
int size = 10000;
int *a;
a = malloc(size);
This second code seems to be working fine.
My question is then, which form is correct? If the second form is, am I allocating needless space with the first form.
The argument to malloc is the number of bytes to be allocated. If you need space for an array of n elements of type T, call malloc(n * sizeof(T)). malloc does not know about types, it only cares about bytes.
The only exception is that when you allocate space for (byte/char) strings, the sizeof can be omitted because sizeof(char) == 1 per definition in C. Doing something like
int *a = malloc(10000);
a[9000] = 0;
may seem to work now, but actually exploits undefined behavior.
malloc allocates a given number of bytes worth of memory, suitably aligned for any type. If you want to store N elements of type T, you need N * sizeof(T) bytes of aligned storage. Typically, T * p = malloc(N * sizeof(T)) provides that and lets you index the elements as p[i] for i in [0, N).
From the man page:
The malloc() function allocates size bytes and returns a pointer to the allocated memory.
The first form is correct.
Even if the sizeof(int) on the machine you are targeting is one (which is sometimes true on 8-bit microcontrollers) you still want your code to be readable.
The reason the "second code seems to be working fine" is that you are lucky.
The version of malloc you are using might be returning a pointer to an area of memory that is larger than what you requested. No matter what is happening behind the scenes, the behavior may change if you switch to a different compiler, so you do not want to rely on it.
My goal is to read a file and store it's contents in a char array given the offset and number of bytes to be read. I have written a function for doing the same and it works fine.
Now this function is to be called from somewhere else. So I am trying to declare a variable char * data which will hold the contents returned by the above mentioned function. After declaring I tried to allocate it some memory. (I know how much, as I specify the number of bytes to be read). It goes as follows:
char * data;
char * filename = "alphabet.txt";
int data_size = 10;
printf("data size: %d\n", data_size);
data = (char*) malloc (data_size);
printf("Size allocated to data: %d\n",sizeof(data));
return 0;
This code gives the following output:
data size: 10
Size allocated to data: 8
I don't understand this behavior. Can somebody please explain it to me.
Thanks a lot
shahensha
This has nothing to do with malloc.
sizeof does its thing at compile time, not runtime. sizeof(data) is the same as sizeof(char*). Your program cannot know at compile time how much memory that pointer refers to.
On the other hand, sizeof(some_array) would work as you expect because array sizes are known at compile time.
sizeof char *ptr will give the sizeof the pointer address ptr pointing . Its vary depends on the machine.
char *ptr = malloc(10); malloc will allocate the 10 space and ptr pointing
to the starting address.
Examine below code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char * data;
int data_size = 10;
printf("data size: %d\n", data_size);
data = malloc ((data_size+1)*sizeof(char));
strcpy(data, "datadatada");
printf("string lenght: %d\n",strlen(data));
printf("Size allocated to data: %zd\n",sizeof(data));
return 0;
}
Just these two lines of code
char * data;
printf("Size allocated to data: %d\n",sizeof(data));
would print (in OP's machine):
Size allocated to data: 8
sizeof returns the size of the argument, here data pointer. It is done at compile time.
malloc has nothing to do with sizeof(data).
Apparently you made some completely unfounded assumptions about the behavior of sizeof. Apparently you assumed that sizeof can be used to query the size of malloc-ed memory block.
It can't be. sizeof has absolutely nothing to do with that. In fact, C library does not provide you with any means to determine the size of malloc-ed memory block. It is simply impossible. If you want to know how much memory you allocated, you have to devise your own way to remember how much memory you requested from malloc. End of a story.
sizeof evaluates to the size of its operand. In this case you supplied a pointer as its operand, so it evaluated to the size of a pointer, which happens to be 8 on your platform.
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.
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
newbie questions about malloc and sizeof
I am trying to read strings into a program. When I noticed that the strings were sometimes being corrupted, I tried the following code:
void *mallocated = malloc(100);
printf("sizeof(mallocated) = %d\n", sizeof(mallocated));
According to my program, the size of mallocated was 8, even though I allocated 100 bytes for it. Because of this, whenever I try to store a string longer than 8 bytes, everything after the 8th byte will sometimes disappear. Why is this happening, and how can I prevent it?
Because the size of the "string" pointer is 8 bytes. Here are some examples of using sizeof() with their appropriate "size". The term size_of() is sometimes deceiving for people not used to using it. In your case, the size of the pointer is 8 bytes.. below is a representation on a typical 32-bit system.
sizeof (char) = 1
sizeof (double) = 8
sizeof (float) = 4
sizeof (int) = 4
sizeof (long) = 4
sizeof (long long) = 8
sizeof (short) = 2
sizeof (void *) = 4
sizeof (clock_t) = 4
sizeof (pid_t) = 4
sizeof (size_t) = 4
sizeof (ssize_t) = 4
sizeof (time_t) = 4
Source
You are leaving out how you are determining your string is disappearing (char array). It is probably being passed to a function, which you need to pass the explicit length as a variable or track it somewhere. Using sizeof() won't tell you this.
See my previous question about this and you'll see even my lack of initial understanding.
In C89, sizeof operator only finds the size of a variable in bytes at compile time (in this case a void pointer of 8 bytes). It works the way you'd expect it to work on plain arrays, because their size is known at compile time.
char arr[100]; // sizeof arr == 100
char *p = arr; // sizeof p == 4 (or 8 on 64-bit architectures)
char *p = malloc(100); // sizeof p == 4 (or 8). Still!
To know the size of heap-allocated memory, you need to keep track of it manually, sizeof won't help you.
sizeof returns the size of the pointer (void *) that you gave it, not the size of the memory you allocated. You would have to store the size of the memory in a separate variable if you want to use it later.
You cannot. As pointed out, you can get the size of the void * mallocated, but that does not tell you much.
You cannot get the size of the malloed *mallocated. That is to say, there is no function call to return 100 (in your example) - unless you write your own memory management routines.
Simplest is just to remember it somewhere ... maybe ....
stuct {
void *data;
unsigned int size
} myStructureWhichRemebersItsSize;
myStructureWhichRemebersItsSize *someData;
someData.data = malloc(100); // and check for NULL
someData.size = 100;
void* is the type of a location in memory if you don't know what it contains. It should be avoided.
char* is the type of a value which points to some location in memory which holds a char. Identifying a location in memory takes eight bytes.
sizeof tells you how many bytes a particular type takes. Not how many were allocated with malloc but just how much memory compiler knows the type should take. Applying sizeof to values is often considered bad style, and as someone else mentioned here, sometimes invokes smart behavior in C99.
char[100] the type of a value which holds 100 chars. char[100] a; is a string of 100 chars on the stack.
char(*)[100] is the type of a pointer to a value that holds 100 chars. char(*b)[100]; makes b point to 100 chars, possibly on the heap. What you probably want is
char (*s)[100] = malloc( sizeof( char[100] ) );
printf( "%u byte pointer to %u bytes of size %u elements\n",
sizeof s, sizeof *s, sizeof **s );