This question already has answers here:
How can I get the size of an array from a pointer in C?
(16 answers)
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Find malloc() array length in C? [duplicate]
(4 answers)
Closed 4 years ago.
Is there any way I could find how much bytes are allocated for RandomArray in this code
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *RandomArray;
int n;
srand(time(NULL));
RandomArray=malloc(sizeof *RandomArray * (rand()%11));
printf("%d %d",sizeof(RandomArray),sizeof(*RandomArray));
return 0;
}
Also I don't know whether above code will ever have any kind of practical usage. But I am looking from programming perspective.
Ah this is experimental code. Interesting things are there.
You will allocate memory for N integers where N is between 0 to 10 including 0 and 10.
Then you applied sizeof to the pointer (int*) and what it points to (int). It won't matter how much memory you allocate. The output from this line will be same.
There is no error check here. if it was you couldn't tell whether it is successful entirely surely because rand() may give 0 as result. You need to store it somewhere and check whether it is 0 because on that case malloc may or may not return NULL.
Printing what sizeof returns should be done using %zu format specifier. It returns size_t.
To be more clear remember it is a pointer pointing to dynamically allocated memory. RandomArray is not an array - it is an pointer pointing to contiguous memory. That doesn't make it array. It is still a pointer. And the sizeof trick that you wanted to apply thinking RandomArray is an array won't work. In general we keep track of it - using some variable. But here you don't know how much memory you allocated.
malloc may return NULL when you pass 0 to it. Handle that case separately. In case you get sz!=0 and get NULL in RandomArray throw error.
size_t sz = rand()%11;
RandomArray = malloc(sz);
if(!RandomArray && sz){
perror("malloc");
exit(EXIT_FAILURE);
}
After all this talk - the short answer is, with this setup there is no use of the code (code you have written) so far. You don't know what rand() returned on that case inside malloc.
Since the expression *RandomArray is of type int, sizeof(*RandomArray) evaluates to sizeof(int). It does not tell you how much memory was allocated.
When dynamically allocating memory, you need to keep track of how much was allocated yourself. In the case above, you would need to store the random number someplace so you know what that amount is.
Yes, by saving the size in a variable:
int main()
{
int *RandomArray;
int n;
srand(time(NULL));
size_t size = rand() % 11;
if(size == 0)
{
fprintf(stderr, "Size 0, no point in allocating memory\n");
return 1;
}
RandomArray = malloc(size * sizeof *RandomArray)
if(RandomArray == NULL)
{
fprintf(stderr, "no memory left\n");
return 1;
}
printf("%zu %zu\n", sizeof(RandomArray), size);
// don't forget to free the memory
free(RandomArray);
return 0;
}
Note that sizeof(RandomArray) returns you the size that a pointer to int
needs to be stored in memory, and sizeof(*RandomArray) returns you the size of
an int.
Also don't forget to free the memory.
sizeof(RandomArray) always results in 4 bytes(equal to pointer size), if you want to find how many bytes allocated for RandomArray
/* Since its implimentation dependent, so I'm not
advising you to access RandomArray[-1], also proper type casting needed */
printf("memory allocated = %d \n",RandomArray[-1]);
From
The C programming language by Denis Ritchie & Kernighan
typedef long Align; /* for alignment to long boundary */
union header { /* block header */
struct {
union header *ptr; /* next block if on free list */
unsigned size; /* size of this block */
} s;
Align x; /* force alignment of blocks */
};
typedef union header Header;
The Align field is never used;it just forces each header to be aligned on a worst-case boundary.
In malloc,the requested size in characters is rounded up to the proper number of header-sized units; the block that will be allocated contains
one more unit, for the header itself, and this is the value recorded in the
size field of the header.
The pointer returned by malloc points at the free space, not at the header itself.
RandomArray[-1]
-----------------------------------------
| | SIZE | |
-----------------------------------------
RandomArray
-> a block returned by malloc
The sizeof operator works at compile time, except for the case when the operand is variable length array, and the dynamic memory allocation is run time operation.
In the expression:
printf("%d %d",sizeof(RandomArray),sizeof(*RandomArray));
the type of RandomArray is int * and the type of *RandomArray is int.
Hence, the expression is equivalent to:
printf("%d %d",sizeof(int *),sizeof(int));
for which the sizeof will yield the result as an integer constant and therefore, you will get the same result every time irrespective of the size of memory allocate to RandomArray.
How to find the size of dynamic array
Keep the track of the size from the point where you are allocating memory dynamically.
Beware, you are multiplying the value returned by rand()%11 to the sizeof *RandomArray while allocating memory and rand() may return 0 as well which will lead to malloc(0). Good to know that (from C Standards#7.22.3):
....If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.
Related
A part of my main contains
int* p = NULL;
p = malloc(sizof(int)*10);
p = realloc(p, sizeof(int) * 5);
free(p);
Is there any way to find out if, after reallocation, the pointer p points to a memory block of size 20 bytes and not 40 bytes anymore?
The ideal would be to have a function that takes an address of memory as argument and tells if it's allocated or free. Is there such a function?
Another idea would be to check the size before and after the realloc() of the allocated memory. But I don't see how sizeof() could help, because how would I identify the block of memory, sizeof() sends the size of variables and not the size of a block of memory. sizeof(p) will give me 8 bytes, since p is a pointer and sizeof(*p) is 4, since p points to an integer.
Maybe there is a special use of sizeof() or some another function?
Read more if you want to know why I ask...
If I initialize my p to hold/point to an array
for (int i = 0; i < 3 ; i++){
p[i] = i;
}
I want now p to hold only {0,1,2} so I want to reallocate p from sizeof(int)* 5 to sizeof(int)*3.
But let's say I don't really know if p should be reallocated, the memory block is 20 bytes, but maybe it's already 12 bytes, and realloc() is not needed. I know I can run realloc() either way and it won't hurt, so maybe it's not really a good reason for this question. But in a longer code it's easy to lose track of the amount of allocated memory.
Any help will be much appreciated.
PS: if no one answers I will have to get satisfaction from valgrind sending 0 errors.
After all, if something is wrong, for example writing in 21st, 22nd, 23rd and 24th bytes of memory (ex: p[4] = 7) of a block of 20 bytes (because p = realloc(p, sizeof(int) * 5)) valgrind sends errors of type "invalid write of size 4", but to get that I need to write in this memory. This method of verification makes me want to get errors, because if I can accurately predict an error then I know the actual size of the allocated memory.
There is no portable way of checking it.
You need to keep the size information yourself.
typedef struct String
{
size_t size;
int data[];
}data_type;
data_type *allocate(data_type *dt, size_t size)
{
if(!dt || dt -> size != size)
{
dt = realloc(dt, sizeof(*dt) + size * sizeof(dt -> data[0]));
if(dt)
{
dt -> size = size;
}
}
return dt;
}
Usage is the same as realloc. If you pass NULL pointer it will allocate the the stricture and space for data. If you change the size, save the result in the temporary pointer and check if allocation did not fail. If the requested size is the same as the actual allocated space it will do nothing (as reallocation is not needed)
Is there any way to find out if, after reallocation, the pointer p points to a memory block of size 20 bytes and not 40 bytes anymore?
No
This method of verification makes me want to get errors, because if I can accurately predict an error then I know the actual size of the allocated memory.
Use -fsanitize=address for both compiler and linker. Read more here: https://stackoverflow.com/a/40215639/6699433
I want to create a variable length array for my code in the Visual Studio 2010 environment.
I had tried the code using the array of length x, as it is passing by the user. But I am facing the error as:
"error C2466:cannot allocate an array of constant size 0" ,"error C2133: 'v_X_array' : unknown size".
func1(int x)
{
int v_X_array[x];
int i;
for (i=0; i<x; i++)
{
v_X_array[i] = i;
}
}
I expect the answer as v_X_array[0] = 0, v_X_array[1] =1, v_X_array[2]=2 ... v_X_array[10]=10 ; for x = 10;
How can I do this?
Note: as calloc and malloc should not be used.
If you need your code to be portable, you cannot use that kind of array definition to handle memory areas.
Without going into specific implementations, you have two generic approaches that you can use:
Define an array big enough for the worst case. This is tightly dependent on the application, so you are on your own.
Define the "array" using dynamic allocation. With that, you can define memory areas of any arbitrary size.
If you choose option 2:
a. Do not forget to de-allocate the memory when you no longer need it.
b. To avoid frequent allocation and de-allocation, you may define the buffer once (perhaps bigger then necessary for the current call) and use it several times. You may and up with the same result as option 1 above - define a large array from the start.
Since you should not use dynamic allocation ("calloc and malloc should not be used"), then you are left with option 1.
I expect the ans as v_X_array[0] = 0, v_X_array[1] =1, v_X_array[2]=2 ... v_X_array[10]=10 ; for x = 10;
You expect to store 11 values in an array which can hold only 10?
You can't allocate an array of an unknown size.
So you need to allocate it dynamically "at run-time".
you can make this allocation using "new" in C++ or "malloc" in C.
For example:
In C++ if you want to allocate an array of an unknown size you should do the following:
int* v_X_array = new int[x];
int i;
for (i=0; i<x; i++)
{
v_X_array[i] = i;
}
The reason that we use integer pointer is that "new" returns the base address of the array "the address of the first element", so the only thing that can store addresses is pointers.
In C if you want to allocate an array of an unknown size you should do the following:
int* v_X_array = (int*) malloc(x*sizeof(int));
int i;
for(i=0; i<x; i++)
{
v_X_array[i] = i;
}
The malloc function takes a single argument which specifies the number of bytes to be allocated and returns a void pointer so the casting (int*) is required.
For more explanations, look at the next section:
If we need to allocate an array of 20 integers it could be as follow: "malloc(20*sizeof(int))" where 20 is the number of allocated elements and sizeof(int) is the size of the type you want to allocate. If successful it returns a pointer to memory allocated. If it fails, it returns a null pointer.
Enter image description here
I have a question about dynamic memory allocation.
Context: I'm writing a program that reads a text file of words and counts the frequency with which each word occurs (one word per line).
This particular function reads the file, counts the lines and characters, then dynamically allocates memory to the array of string pointers, an array storing the count of characters for each line and the strings themselves. (The other parts are less directly relevant to my question).
Question: How often should I reallocate memory if I run out of space? I set a constant ("memstart") for setting the initial memory allocation value. In the below code snippet I realloc for every line over the value of "memstart". Would the program process faster if a reallocated a larger block of memory instead of increasing the memory space by 1 "variable type" each time?
What would be best practice for something like this?
Code Snip:
int read_alloc(FILE* fin, FILE *tmp, char **wdp, int *sz){
int line_cnt= 0, chr, let=1;
do{
chr=getc(fin);
let++;
//count characters
if(chr!=EOF){
chr=tolower(chr);
fputc(chr, tmp);
}
//convert to lcase and write to temp file
if ('\n' == chr || chr==EOF){
sz[(line_cnt)]=((let)*sizeof(char)); //save size needed to store string in array
*(wdp+(line_cnt))=malloc((let)*sizeof(char)); //allocate space for the string
if ((line_cnt-1) >= memstart){
realloc(wdp, (sizeof(wdp)*(memstart+line_cnt))); //if more space needed increase size
realloc(sz, (sizeof(sz)*(memstart+line_cnt)));
}
line_cnt++;
let=1;
}
} while (EOF != chr);
return (line_cnt);
}
While the question is about how often realloc should be called, looking at OP's code, I think it's better to start with how safely it should be done.
The C11 standard states (n1570 draft, § 7.22.3.5, The realloc function, emphasis mine):
Synopsis
#include <stdlib.h>
void *realloc(void *ptr, size_t size);
Description
The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values.
If ptr is a null pointer, the realloc function behaves like the malloc function for the specified size. (...). If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged.
Returns
The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated.
Now let's consider this snippet from the question, where sz is declared as int* sz;
realloc(sz, (sizeof(sz)*(memstart+line_cnt)));
The return value is lost, so we can't know if the call succeeded and if it did, sz is invalidated. Moreover, sizeof(sz) is the size of the pointer, not of the pointed type (int).
A more safe (and correct) pattern would be:
size_t new_size = /* Whatever, let's say */ size + SOME_COSTANT + size / 2;
void *tmp = realloc(ptr, new_size * sizeof *ptr);
if ( tmp == NULL ) {
/* Deal with the error, e.g. log a message with perror, return NULL
(if this is in a function) or just give up, but remeber that
realloc doesn't invalidate nor free 'ptr' on failure */
exit(EXIT_FAILURE);
}
ptr = tmp; // <- on success, realloc invalidated ptr
size = new_size;
Now, to answer the question, realloc should be called only when needed, because it involves potentially expansive system calls. So either allocate a big chunk ahead or choose a growing stratey like doubling (or 1.5 times) the size every time.
It's worth noting that if possible, the OS could perform the reallocation without copying any element of the original array.
The classic answer is to double each time, but a factor of 1.5 might be better. The important bit is that you multiply your array size by some factor each time, rather than adding additional space each time.
Each re-allocation might need to copy the previous array into a new one. We'd like to minimize these copies. If we will be adding n items, and we start with an array of size a, increase by a factor of r each re-allocation, to end with a value of n, the sequence of (re-)allocations will be a, ar, ar^2, ar^3, ..., n. The sum of that sequence is (nr-a)/(r-1). Thus the total space is of order O(n).
Suppose instead we start with a, and this time add r each time. The sequence is a, a+r, a+2r, a+3r, ..., n. The sum of that sequence will be 0.5*((n^2-a^2)/r + a + n). In this case the total space of order O(n^2). Much worse!
With a constant factor of 2, the array will be in the worse case 1/2 empty. That's probably ok. You can always shrink the allocation when you're done and know the final size.
As pointed out in another answer, there are several bugs in the manner in which you call realloc(), but that wasn't the question.
struct busData{
int busNum;
char str[SIZE+1]; //SIZE = 1000
};
int main(){
struct busData *bus = (struct busData*)calloc(5, sizeof(struct busData));
printf("\n%d", sizeof(bus)); //result is 4
free(bus);
return 0;
}
Now It is showing '4' or '8'depending on platform as a result. I think it should display 5040 right? Because I gave 5 value with calloc(). So how can I get 5040? i am using the 3 elements until 'bus+2' and then I am freeing up with free(bus); And i want to know how many elements left (it should show 2008). so i need 5040?
sizeof(bus)
Here bus is a pointer so sizeof() will return 4 which is the size of the pointer in the platform you used.(depending on the platform used).
If you want to know the size of struct use sizeof(struct busData) or sizeof(*bus)
You are trying to output the size of the pointer bus instead of the 5 objects pointed to by the pointer.
Try the following demonstrative program
#include <stdio.h>
#include <stdlib.h>
#define SIZE 1000
struct busData
{
int busNum;
char str[SIZE+1]; //SIZE = 1000
};
int main(void)
{
struct busData *bus = (struct busData*)calloc(5, sizeof(struct busData));
printf("\n%zu\n", 5 * sizeof( *bus ) );
return 0;
}
The program output is
5040
Pay attention to the conversion specifier and the expression used as an argument of the printf call
printf("\n%zu\n", 5 * sizeof( *bus ) );
^^ ^^^^^^^^^^^^^^^^^
Take into account that pointers do not provide information whether they point to a single object or first object of an array of objects. So using the pointer bus you have to specify explicitly how many objects are pointed to by the pointer.
The same result you could get executing the following statement
printf("\n%zu\n", sizeof( struct busData[5] ) );
Now It is showing '4' as a result. I think it should display 5040 right?
No, you're wrong. Check the data types.
First of all, a little about sizeof operator, from C11, chapter §6.5.3.4
The sizeof operator yields the size (in bytes) of its operand, which may be an
expression or the parenthesized name of a type. The size is determined from the type of
the operand. [...]
bus is a pointer, so, sizeof(bus) is the same as sizeof (struct busData*), which is the size of a pointer, which depending on your environment, can give you the result, of which, the common nones are 4 or 8.
After that, there can be padding in between structure elements and at the end, so a structure defined like
struct busData{
int busNum;
char str[SIZE+1]; //SIZE = 1000
};
defining a variable of that type and trying to check the size via sizeof may not give you (4+1000+1) == 1005 bytes, for most of the environments.
Quoting again,
[....] When
applied to an operand that has structure or union type, the result is the total number of
bytes in such an object, including internal and trailing padding.
So, you need to account for padding also.
That said,
printf("\n%d", sizeof(bus));
actually causes undefined behavior. You need to write
printf("\n%zu", sizeof(bus));
as sizeof yields a result of type size_t.
I think the code is screwed up from the beginning.
The problem with sizeof was already explained in other answers.
Another big problem is this:
Because I gave 5 value with calloc(). So how can I get 5040?
i am using the 3 elements until 'bus+2'
and then I am freeing up with free(bus);
And i want to know how many elements left (it should show 2008).
so i need 5040?
This sounds like you want to use the remaining 2 elemens after calling free.
First:
you have 1 pointer. The compiler can tell you the size of the pointer and the size of the single element that the pointer is pointing to.
The compiler has no idea that you allocated memory for more than 1 element of that type and hence cannot tell you anything different than size of pointer or size of 1 element.
Second:
There is no concept like "using" some memory. For the compiler and the OS it doesn't matter if you write something to the memory location or not. It doesn't care if some bytes are still (or again) filled with 0.
Third:
If you allocate a block of memory and free it again, the whole block is free'd and mustn't be used any longer. If you expect to have 2008 bytes that you still can use, you are wrong! Your pointer will point to an invalid address after free is called. Using that pointer to access the memory afterwards is undefined behaviour
How can i identify the size of structure member?
With a pointer to dynamic allocated memory, there is no way to know the size of memory that the pointer points to.
If you need to know the size after the malloc/calloc, you'll simply have to "remember" how much you malloc/calloced, i.e. save it in a variable.
You could wrap it inside another struct and provide a create function. Something like:
struct busData{
int busNum;
char str[SIZE+1]; //SIZE = 1000
};
struct busDataContainer{
size_t size;
struct busData* busData;
};
struct busDataContainer createBusData(size_t n)
{
struct busDataContainer c;
c.size = n * sizeof(struct busData);
c.busData = calloc(n, sizeof(struct busData));
return c;
}
int main(){
struct busDataContainer bus = createBusData(5);
printf("\n%zu", bus.size;
return 0;
}
I know that it's a common convention to pass the length of dynamically allocated arrays to functions that manipulate them:
void initializeAndFree(int* anArray, size_t length);
int main(){
size_t arrayLength = 0;
scanf("%d", &arrayLength);
int* myArray = (int*)malloc(sizeof(int)*arrayLength);
initializeAndFree(myArray, arrayLength);
}
void initializeAndFree(int* anArray, size_t length){
int i = 0;
for (i = 0; i < length; i++) {
anArray[i] = 0;
}
free(anArray);
}
but if there's no way for me to get the length of the allocated memory from a pointer, how does free() "automagically" know what to deallocate when all I'm giving it is the very same pointer? Why can't I get in on the magic, as a C programmer?
Where does free() get its free (har-har) knowledge from?
Besides Klatchko's correct point that the standard does not provide for it, real malloc/free implementations often allocate more space then you ask for. E.g. if you ask for 12 bytes it may provide 16 (see A Memory Allocator, which notes that 16 is a common size). So it doesn't need to know you asked for 12 bytes, just that it gave you a 16-byte chunk.
You can't get it because the C committee did not require that in the standard.
If you are willing to write some non-portable code, you may have luck with:
*((size_t *)ptr - 1)
or maybe:
*((size_t *)ptr - 2)
But whether that works will depend on exactly where the implementation of malloc you are using stores that data.
After reading Klatchko's answer, I myself tried it and ptr[-1] indeed stores the actual memory (usually more than the memory we asked for probably to save against segmentation fault).
{
char *a = malloc(1);
printf("%u\n", ((size_t *)a)[-1]); //prints 17
free(a);
exit(0);
}
Trying with different sizes, GCC allocates the memory as follows:
Initially memory allocated is 17 bytes.
The allocated memory is atleast 5 bytes more than requested size, if more is requested, it allocates 8 bytes more.
If size is [0,12], memory allocated is 17.
If size is [13], memory allocated is 25.
If size is [20], memory allocated is 25.
If size is [21], memory allocated is 33.
While it is possible to get the meta-data that the memory allocator places preceding the allocated block, this would only work if the pointer is truly a pointer to a dynamically allocated block. This would seriously affect the utility of function requiring that all passed arguments were pointers to such blocks rather than say a simple auto or static array.
The point is there is no portable way from inspection of the pointer to know what type of memory it points to. So while it is an interesting idea, it is not a particularly safe proposition.
A method that is safe and portable would be to reserve the first word of the allocation to hold the length. GCC (and perhaps some other compilers) supports a non-portable method of implementing this using a structure with a zero length array which simplifies the code somewhat compared to a portable solution:
typedef struct
{
size_t length ;
char alloc[0] ; // Compiler specific extension!!!
} tSizedAlloc ;
// Allocating a sized block
tSizedAlloc* blk = malloc( sizeof(tSizedAlloc) + length ) ;
blk->length = length ;
// Accessing the size and data information of the block
size_t blk_length = blk->length ;
char* data = blk->alloc ;
I know this thread is a little old, but still I have something to say. There is a function (or a macro, I haven't checked the library yet) malloc_usable_size() - obtains size of block of memory allocated from heap. The man page states that it's only for debugging, since it outputs not the number you've asked but the number it has allocated, which is a little bigger. Notice it's a GNU extention.
On the other hand, it may not even be needed, because I believe that to free memory chunk you don't have to know its size. Just remove the handle/descriptor/structure that is in charge for the chunk.
A non-standard way is to use _msize(). Using this function will make your code unportable. Also the documentation is not very clear on wheteher it will return the number passed into malloc() or the real block size (might be greater).
It's up to the malloc implementor how to store this data. Most often, the length is stored directly in front of the allocated memory (that is, if you want to allocate 7 bytes, 7+x bytes are allocated in reality where the x additional bytes are used to store the metadata). Sometimes, the metadata is both stored before and after the allocated memory to check for heap corruptions. But the implementor can as well choose to use an extra data structure to store the metadata.
You can allocate more memory to store size:
void my_malloc(size_t n,size_t size )
{
void *p = malloc( (n * size) + sizeof(size_t) );
if( p == NULL ) return NULL;
*( (size_t*)p) = n;
return (char*)p + sizeof(size_t);
}
void my_free(void *p)
{
free( (char*)p - sizeof(size_t) );
}
void my_realloc(void *oldp,size_t new_size)
{
// ...
}
int main(void)
{
char *p = my_malloc( 20, 1 );
printf("%lu\n",(long int) ((size_t*)p)[-1] );
return 0;
}
To answer the question about delete[], early versions of C++ actually required that you call delete[n] and tell the runtime the size, so it didn't have to store it. Sadly, this behaviour was removed as "too confusing".
(See D&E for details.)