Memory allocation (calloc, malloc) for unsigned int - c

For my C application I tried to initialize memory. I am aware of the slower calloc, but fortunatelly there is no need to track performance.
I need memory space for just one unsigned int element (up to 65535).
This is the part of my code that doesn't work:
//Declaration
unsigned int part1;
//Allocation
part1 = (unsigned int) calloc (1,sizeof(unsigned int));
That throws the compiler warning:
warning: cast from pointer to integer of different size
[-Wpointer-to-int-cast]
Why does the above code doesn't work, where...
unsigned long size;
size =(unsigned long) calloc (1,sizeof(unsigned long));
...works great?
Thank you!

calloc returns void* so you should use it like
unsigned int* part1 = calloc (1,sizeof(*part1));
then assign it like
*part1 = 42;
If you have allocated space for several elements
part1[0] = 42; // valid indices are [0..nmemb-1]
may be clearer.
Note that you also have to free this memory later
free(part1);
Alternatively, if you only need a single element, just declare it on the stack
unsigned int part1 = 42;
Regarding why casting a point to unsigned long doesn't generate a warning, sizeof(void*)==sizeof(unsigned long) on your platform. Your code would not be portable if you relied on this. More importantly, if you use a pointer to store a single integer, you'd leak your newly allocated memory and be unable to ever store more than one element of an array.

Use code below. Calloc() will return void* So you will have to convert it in the SomeType*
unsigned int* part1;
//Allocation
part1 = (unsigned int*) calloc (1,sizeof(unsigned int));

you have to understand these types of memory allocation to avoid doing these errors :
Static memory allocation:
unsigned int part1;
The size is fixed. It needs to be known at compile time. Freeing the memory is done on scope exit directly. The variable is allocated on the stack.
indeed, this type of memory allocation is done at compile time, its lifetime is entire runtime of program.
the advantage of using this type of allocation is efficient execution time.
but if we declare more static data space than we need we waste space, this is the disadvantage of this type.
Dynamic memory allocation:
unsigned int* part1 = calloc( n, sizeof(unsigned int) );
The size can vary, you can find the value at runtime. You are responsible for freeing the memory with free() predefined C function. The variable is allocated on the heap.
you can see more details in web site : http://www.cs.virginia.edu/~son/cs414.f05/lec11.slides.pdf

Related

Why malloc( ) is used ? And why the size of the variable isn't increasing?

According to the answer from my faculty malloc dynamically allocates memory, Then why the output shows the same size allocated to both normal variable and malloc();. I am a newbie to programming, so I guess you would answer my question the way that a newbie can understand.
#include<stdio.h>
int main()
{
int a,b;
a = (int *) malloc(sizeof(int)*2);
printf("The size of a is:%d \n",sizeof(a));
printf("The size of b is:%d \n",sizeof(b));
return 0;
}
Output:
The size of a is:4
The size of b is:4
Malloc is used on a pointer. You are declaring an integer int a. This needs to be changed to int *a
The sizeof() operator will not give the no of bytes allocated by malloc. This needs to be maintained by the programmer and typically cannot be determined directly from the pointer.
For int *a, sizeof(a) will always return the size of the pointer,
int *a;
printf("%zu\n",sizeof(a)); // gives the size of the pointer e.g. 4
a = malloc(100 * sizeof(int));
printf("%zu\n",sizeof(a)); // also gives the size of the pointer e.g. 4
You should always remember to free the memory you have allocated with malloc
free(a);
Edit The printf format specifiers should be %zu for a sizeof() output. See comments below.
You declare and define both variables as int. Nothing else has an influence on the value of sizeof().
int a,b;
This assigns a value to one of those ints which which is very special, but it does not change anything about the fact that a remains an int (and your cast is misleading and does not do anything at all, even less to change anything about a).
a = (int *) malloc(sizeof(int)*2);
In order to change above line to something sensible (i.e. a meaningful use of malloc) it should be like this:
int* a;
a= malloc(sizeof(int)*2);
I.e. a is now a pointer to int and gets the address of an area which can store two ints. No cast needed.
That way, sizeof(a) (on many machines) will still be 4, which is often the size of a pointer. The size of what it is pointing to is irrelevant.
The actual reason for using malloc() is determined by the goal of the larger scope of the program it is used for. That is not visible in this artificially short example. Work through some pointer-related tutorials. Looking for "linked list" or "binary tree" will get you on the right track.
What programs which meaningfully use malloc have in common is that they are dealing with data structures which are not known at compile time and can change during runtime. The unknown attributes could simply be the total size, but especially in the case of trees, the larger structure is usually unknown, too.
There is an interesting aspect to note when using malloc():
Do I cast the result of malloc?

(int*) when dynamically allocating array of ints in c

So I'm a bit confused on how to make a function that will return a pointer to an array of ints in C. I understand that you cannot do:
int* myFunction() {
int myInt[aDefinedSize];
return myInt; }
because this is returning a pointer to a local variable.
So, I thought about this:
int* myFunction(){
int* myInt = (int) malloc(aDefinedSize * sizeof(int));
return myInt; }
This gives the error: warning cast from pointer to integer of different size
This implies to use this, which works:
int* myFunction(){
int* myInt = (int*) malloc(aDefinedSize * sizeof(int));
return myInt; }
What I'm confused by though is this:
the (int*) before the malloc was explained to me to do this: it tells the compiler what the datatype of the memory being allocated is. This is then used when, for example, you are stepping through the array and the compiler needs to know how many bytes to increment by.
So, if this explanation I was given is correct, isn't memory being allocated for aDefinedSize number of pointers to ints, not actually ints? Thus, isnt myInt a pointer to an array of pointers to ints?
Some help in understanding this would be wonderful. Thanks!!
So, if this explanation I was given is correct, isn't memory being allocated for aDefinedSize number of pointers to ints, not actually ints?
No, you asked malloc for aDefinedSize * sizeof(int) bytes, not
aDefinedSize * sizeof(int *) bytes. That's the size of memory you get, the type depends on the pointer used to access the memory.
Thus, isnt myInt a pointer to an array of pointers to ints?
No, since you defined it as a int *, a pointer-to-an-int.
Of course the pointer has no knowledge of how large the allocated memory are is, but only points at the first int that fits there. It's up to you as programmer to keep track of the size.
Note that you shouldn't use that explicit typecast. malloc returns a void *, that can be silently assigned to any pointer, as in here:
int* myInt = malloc(aDefinedSize * sizeof(int));
Arithmetic on the pointer works in strides of the pointed-to type, i.e. with int *p, p[3] is the same as *(p+3), which means roughly "go to p, go forward three times sizeof(int) in bytes, and access that location".
int **q would be a pointer-to-a-pointer-to-an-int, and might point to an array of pointers.
malloc allocates an array of bytes and returns void* pointing to the first byte. Or NULL if the allocation failed.
To treat this array as an array of a different data type, the pointer must be cast to that data type.
In C, void* implicitly casts to any data pointer type, so no explicit cast is required:
int* allocateIntArray(unsigned number_of_elements) {
int* int_array = malloc(number_of_elements * sizeof(int)); // <--- no cast is required here.
return int_array;
}
Arrays in C
In C, you want to remember that an array is just an address in memory, plus a length and an object type. When you pass it as an argument to a function or a return value from a function, the length gets forgotten and it’s treated interchangeably with the address of the first element. This has led to a lot of security bugs in programs that either read or write past the end of a buffer.
The name of an array automatically converts to the address of its first element in most contexts, so you can for example pass either arrays or pointers to memmove(), but there are a few exceptions where the fact it also has a length matters. The sizeof() operator on an array is the number of bytes in the array, but sizeof() a pointer is the size of a pointer variable. So if we declare int a[SIZE];, sizeof(a) is the same as sizeof(int)*(size_t)(SIZE), whereas sizeof(&a[0]) is the same as sizeof(int*). Another important one is that the compiler can often tell at compile time if an array access is out of bounds, whereas it does not know which accesses to a pointer are safe.
How to Return an Array
If you want to return a pointer to the same, static array, and it’s fine that you’ll get the same array each time you call the function, you can do this:
#define ARRAY_SIZE 32U
int* get_static_array(void)
{
static int the_array[ARRAY_SIZE];
return the_array;
}
You must not call free() on a static array.
If you want to create a dynamic array, you can do something like this, although it is a contrived example:
#include <stdlib.h>
int* make_dynamic_array(size_t n)
// Returns an array that you must free with free().
{
return calloc( n, sizeof(int) );
}
The dynamic array must be freed with free() when you no longer need it, or the program will leak memory.
Practical Advice
For anything that simple, you would actually write:
int * const p = calloc( n, sizeof(int) );
Unless for some reason the array pointer would change, such as:
int* p = calloc( n, sizeof(int) );
/* ... */
p = realloc( p, new_size );
I would recommend calloc() over malloc() as a general rule, because it initializes the block of memory to zeroes, and malloc() leaves the contents unspecified. That means, if you have a bug where you read uninitialized memory, using calloc() will always give you predictable, reproducible results, and using malloc() could give you different undefined behavior each time. In particular, if you allocate a pointer and then dereference it on an implementation where 0 is a trap value for pointers (like typical desktop CPUs), a pointer created by calloc() will always give you a segfault immediately, while a garbage pointer created by malloc() might appear to work, but corrupt any part of memory. That kind of bug is a lot harder to track down. It’s also easier to see in the debugger that memory is or is not zeroed out than whether an arbitrary value is valid or garbage.
Further Discussion
In the comments, one person objects to some of the terminology I used. In particular, C++ offers a few different kinds of ways to return a reference to an array that preserve more information about its type, for example:
#include <array>
#include <cstdlib>
using std::size_t;
constexpr size_t size = 16U;
using int_array = int[size];
int_array& get_static_array()
{
static int the_array[size];
return the_array;
}
std::array<int, size>& get_static_std_array()
{
static std::array<int, size> the_array;
return the_array;
}
So, one commenter (if I understand correctly) objects that the phrase “return an array” should only refer to this kind of function. I use the phrase more broadly than that, but I hope that clarifies what happens when you return the_array; in C. You get back a pointer. The relevance to you is that you lose the information about the size of the array, which makes it very easy to write security bugs in C that read or write past the block of memory allocated for an array.
There was also some kind of objection that I shouldn’t have told you that using calloc() instead of malloc() to dynamically allocate structures and arrays that contain pointers will make almost all modern CPUs segfault if you dereference those pointers before you initialize them. For the record: this is not true of absolutely all CPUs, so it’s not portable behavior. Some CPUs will not trap. Some old mainframes will trap on a special pointer value other than zero. However, it’s come in very handy when I’ve coded on a desktop or workstation. Even if you’re running on one of the exceptions, at least your pointers will have the same value each time, which should make the bug more reproducible, and when you debug and look at the pointer, it will be immediately obvious that it’s zero, whereas it will not be immediately obvious that a pointer is garbage.

How to properly allocate memory using malloc in C

I have a void pointer and I need to properly allocate memory of correct type. Say:
char * array="20080101"
Now, I know the value that this char string contains is a long type. Now, I have a void pointer with me:
void* pointer;
I need to allocate correct amount of memory to it and cast it as a long pointer so it will point to a long value (20080101);
The question is how do we do that? From my research, I know I can allocate it using malloc as:
void *pointer=(long*) malloc(sizeof(long) OR sizeof(long)*strlen(array));// what should be the correct parameter.
How do we make it point to a value of long type? We have our array in string.
Oh, you are a bit confused. First, A pointer, is a pointer, is a pointer, not a long and short pointer (anymore) and they are all the same size (generally 8-bytes on x86_64 and 4-bytes on x86).
Your array points to a null-terminated string literal, containing an apparent encoded date of Jan. 1, 2008. The numeric value 20080101 is easily within the size of an int or unsigned on any system and that is irrelevant to allocating storage for it (unless you are on a `16-bit system).
If you want to convert the string to a long, you can use strtol, e.g.:
long myval = strtol (array, NULL, 10);
for base 10 conversion. The second parameter (above NULL) is actually an endptr that on successful conversion returns a pointer to the next character in array following the number converted (if the string contains additional characters). You will need to include <stdlib.h> to use strtol.
As for your cast question, if you have array and it is passed as void, e.g.
long *somefunction (void *value, long *myval, ...)
Inside some function, you will need to do two things for conversion:
*myval = strtol (value, NULL, 10);
return myval;
Or, if you just need to create a pointer to long from myval, simply create the pointer:
long *lpointer = &myval;
Allocating Storage for array
When you allocate storage dynamically for any string, you need the length of the string (+ 1 for the null-terminator). Here is where you need to understand what sizeof will return and what strlen will return. If you take sizeof anypointer, you do not get the length, you get the pointer size (8-bytes, etc..). When you use sizeof dereferenced pointer you get the type size for the type pointed to (e.g. sizeof *somelongpointer will give you the storage size for a long on your system)
If you are copying the string, it is better to include <string.h> and then:
size_t len = strlen (array);
Then you are ready to allocate storage:
char *mycopy = malloc (len * sizeof *array + 1);
strncpy (mycopy, array, len * sizeof *array + 1);
mycopy then holds the contents of array. Since it was dynamically allocated, you should free it when you no longer need it (e.g. free (mycopy);)
If your intent was to create a pointer to type long and dynamically allocate storage for the long, then you need sizeof to determine the size of a long on your system. e.g.
long *mylong = malloc (sizeof *mylong);
then, (using the same somefunction example):
*mylong = strtol ((char *)value, NULL, 10);
return mylong;
Sorry for the confusion, but that should about cover all cases :).
If you really want to allocate enough memory to hold a long integer, you can do
long* value = malloc(sizeof(*value));
and then assign to it as #David says:
*value = strtol(array, NULL, 10);
However, it is usually simpler to use a local variable to hold integers, not allocate them from the heap.

C: Acces bytes in mallocated memory

I have allocated array of void
I need to acces bytes of allocated memory
void* array = (void*) malloc(12);
array[0] = 0;
It returns me this error:
main.c:9: error: invalid use of void expression
array[0] = 0;
^
Is there any way how to do it ?
Thanks!
Your array is a void-pointer. And void (in C) means 'has no type'. So when you dereference it (like array[0]) the compiler has no idea what that means.
To access bytes you need a char type, which is actually the C-equivalent of a byte (a remnant from the days when characters would still fit into (8-bit) bytes).
So declare your array as:
char * array = malloc(12);
Also note that you don't have to cast the result of malloc (especially in your case since it already returns a void *). And, if you want just the 12 bytes and only use them locally (within the function or translation-unit that declares it) then you can just use a 'proper array':
char array[12];
This has the added bonus that you don't need to free it afterwards.
You need to use char or unsigned char rather than void to access the bytes:
char *array = malloc(12);
array[0] = 0;
malloc() returns a void pointer because it doesn't know the type you're allocating. You can't access the memory via that void pointer; you need to tell the compiler how to treat the block of memory. To treat it as bytes, use char or unsigned char.

casting of an address

You have an operating system, which has 2 functions dealing with memory allocation:
void *malloc( int sz ) // allocates a memory block sz bytes long
void free( void *addr ) // frees a memory block starting at addr
// (previously allocated by malloc)
Using these functions, implement the following 2 functions:
void *malloc_aligned( int sz ) // allocates a memory block sz bytes long,
// aligned to an address divisible by 16
void free_aligned( void *addr ) // frees a memory block starting at addr
// (previously allocated by malloc_aligned)
in the solution there is the following part:
void * aligned_malloc(size_t size){
unsigned char *res=malloc(size+16);
unsigned char offest=16-((long)res%16);
What I don't understand is: Why do we need to use unsigned char and why and what we achieve using 16-((long)res%16); and what is the purpose of (long)res in this case?
You can't do pointer arithmetic on "void *", because void has no size.
When adding to a pointer or subtracting to it, it's always done in units of sizeof(*p). Meaning - if you add one to an int pointer, its value grows by 4 (because the size of an integer is 4). So when you add to a void pointer, it should grow by the size of a void. But void has no size.
However, some compilers are willing to do arithmetic on void *, and they treat it like char *. With these compilers, you could implement these functions without casting. But it isn't standard.
Another point is that not all operators are applicable for pointers. Addition and subtraction are, but multiplication, division and modulus are not. So if you want to test the low bits of a pointer, to know if it's aligned, you cast it to a long.
Why long? The assumption is that long is as large as a pointer, which is true in Linux, but not in Windows. The right type is uintptr_t. However, if you're only interested in the low bits, it doesn't matter if you lose the high bits while casting. So a cast to int would have worked too.

Resources