Freeing Struct Members that are also Structs [duplicate] - c

Is there any way to free some part of memory you created by using malloc();
suppose:-
int *temp;
temp = ( int *) malloc ( 10 * sizeof(int));
free(temp);
free() will release all 20 byte of memory but suppose i only need 10 bytes. Can i free last 10 bytes.

You should use the standard library function realloc. As the name suggests, it reallocates a block of memory. Its prototype is (contained in the header stdlib.h)
void *realloc(void *ptr, size_t size);
The function changes the size of the memory block pointed to by ptr to size bytes. This memory block must have been allocated by a malloc, realloc or calloc call. It is important to note that realloc may extend the older block to size bytes, may keep the same block and free the extra bytes, or may allocate an entirely new block of memory, copy the content from the older block to the newer block, and then free the older block.
realloc returns a pointer to the block of reallocated memory. If it fails to reallocate memory, then it returns NULL and the original block of memory is left untouched. Therefore, you should store the value of ptr in a temp variable before calling realloc else original memory block will be lost and cause memory leak. Also, you should not cast the result of malloc - Do I cast the result of malloc?
// allocate memory for 10 integers
int *arr = malloc(10 * sizeof *arr);
// check arr for NULL in case malloc fails
// save the value of arr in temp in case
// realloc fails
int *temp = arr;
// realloc may keep the same block of memory
// and free the memory for the extra 5 elements
// or may allocate a new block for 5 elements,
// copy the first five elements from the older block to the
// newer block and then free the older block
arr = realloc(arr, 5 * sizeof *arr);
if(arr == NULL) {
// realloc failed
arr = temp;
}

You can use realloc function provided by the standard c library.
C99 Standard 7.20.3.4-1: The realloc function:
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.

Related

Size of array with malloc function

I am learning C programming and this is my first course in programming. I am having some trouble with this snippet of code:
int* intArray;
intArray=(int*)malloc(5*sizeof(int));
I believe the number of elements in the array is 5 integers. However, what I don't really understand is the malloc function. Does it allocate enough memory for the addresses of 5 integers in this case?
Malloc returns a void pointer to the allocated space, or NULL if there is insufficient memory available. The parameter is the size, in bytes, to be allocated. So in the line intArray = (int*)malloc(5*sizeof(int)); you are requesting the allocation of memory sufficient for 5 ints (sizeof(int) gives the size of an int type). (malloc)
Using malloc requests the allocation of memory sufficient for 5 new integers.
No, the malloc allocates enough memory for 5 integers. It allocates what is passed into the function: 5*sizeof(int). What might be confusing you is that intArray is a pointer allocated on the stack, which points to the memory address of the beginning of the malloc'ed memory.
If you want memory for addresses of 5 integers, you would do something like:
int** intArray;
intArray=(int**)malloc(5*sizeof(int*));
The malloc function allocates the number of bytes you request in the argument and returns the address in memory of the beginning of the block. In this case you have requested a block of memory large enough to hold 5 integer values.
You cast it to an int * so the compiler will handle the address as containing integers when indexing and dereferencing.
Malloc function call as you observe requires a value specifying number of bytes. From the documentation on malloc:
void* malloc (size_t size);
Allocate memory block. Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.
The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.
Hence, in your code snippet:
intArray=(int*)malloc(5*sizeof(int));
int size is 2 bytes. sizeof(int) returns 2. Hence 5 * sizeof(int) = 10. So, code resolves to intArray = (int*)malloc(10);

Successive pointer allocations; Reallocated or allocated distinct?

If I allocate memory to pointers in a loop successively, does the compiler consider it as a single instance? Concretely:
for (i = 0; i < SOME_VAL; i++)
{
char *p = NULL;
p = malloc(sizeof(char));
SEND_POINTER_ON_NETWORK(p);
}
Will the compiler at every execution create a new instance of p or will it continue allocating memory to p? I am using VS2010.
char *p = NULL;
p = malloc(sizeof(char));
Each call to malloc() within the loop allocates new memory location to the pointer p , if you are trying to extend the already allocated memory to p then use realloc().
The memory management system looks for a free memory slot at the size of the argument in malloc (in this case sizeof(char)). You do not free the memory from one iteration to the next. Therefore, the memory management system 'sees' the memory as occupied and allocates a new memory slot to pointer p.
You have a memory leak in your code.
From ISO/IEC 9899:
(known as c99 standard)
7.20.3.3 The malloc function
Synopsis
1 #include <stdlib.h>
void *malloc(size_t size);
Description
2 The malloc function allocates space for an object whose size is specified by size and
whose value is indeterminate.
Returns
3 The malloc function returns either a null pointer or a pointer to the allocated space.
The behaving you expect would be made by realloc, which is described as follows:
7.20.3.4 The realloc function
Synopsis
1 #include <stdlib.h>
void *realloc(void *ptr, size_t size);
Description
2 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.
3 If ptr is a null pointer, the realloc function behaves like the malloc function for the
specified size. Otherwise, if ptr does not match a pointer earlier returned by the
calloc, malloc, or realloc function, or if the space has been deallocated by a call
to the free or realloc function, the behavior is undefined. If memory for the new
object cannot be allocated, the old object is not deallocated and its value is unchanged.
Returns
4 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.
Also notable is the fact, that MSVC compiler isn't strict conform to the standard in all topics.
But in the both cited cases I know they are conform with it. So it is also valid for your question.

dynamic memory allocation in c , free some part of memory that is allocated before using malloc()

Is there any way to free some part of memory you created by using malloc();
suppose:-
int *temp;
temp = ( int *) malloc ( 10 * sizeof(int));
free(temp);
free() will release all 20 byte of memory but suppose i only need 10 bytes. Can i free last 10 bytes.
You should use the standard library function realloc. As the name suggests, it reallocates a block of memory. Its prototype is (contained in the header stdlib.h)
void *realloc(void *ptr, size_t size);
The function changes the size of the memory block pointed to by ptr to size bytes. This memory block must have been allocated by a malloc, realloc or calloc call. It is important to note that realloc may extend the older block to size bytes, may keep the same block and free the extra bytes, or may allocate an entirely new block of memory, copy the content from the older block to the newer block, and then free the older block.
realloc returns a pointer to the block of reallocated memory. If it fails to reallocate memory, then it returns NULL and the original block of memory is left untouched. Therefore, you should store the value of ptr in a temp variable before calling realloc else original memory block will be lost and cause memory leak. Also, you should not cast the result of malloc - Do I cast the result of malloc?
// allocate memory for 10 integers
int *arr = malloc(10 * sizeof *arr);
// check arr for NULL in case malloc fails
// save the value of arr in temp in case
// realloc fails
int *temp = arr;
// realloc may keep the same block of memory
// and free the memory for the extra 5 elements
// or may allocate a new block for 5 elements,
// copy the first five elements from the older block to the
// newer block and then free the older block
arr = realloc(arr, 5 * sizeof *arr);
if(arr == NULL) {
// realloc failed
arr = temp;
}
You can use realloc function provided by the standard c library.
C99 Standard 7.20.3.4-1: The realloc function:
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.

realloc vs malloc in C

I'm fairly new to C, and just now starting to venture into the realm of dynamically allocated arrays.
I think i've got mostly malloc down, but had some questions on realloc:
Can realloc be used for anything else besides adding memory space to pointers?
Does the size variable always have to be an int?
Would something like the below work?
float *L = NULL;
int task_count = 5;
L = (float*) realloc (L, task_count * sizeof(float));
If I wanted to increase that space further (by one in this case), could I just use something like the following?
L = (float*) realloc (L, 1 * sizeof(float));
Seems deceptively simple, which tells me I'm possibly missing something.
In case that ptr is a null pointer, the function behaves like malloc, assigning a new block of size bytes and returning a pointer to its beginning.
void * realloc (void* ptr, size_t size);
ptr - Pointer to a memory block previously allocated with malloc, calloc or realloc.
Alternatively, this can be a null pointer, in which case a new block is allocated (as if
malloc was called).
sizeNew - size for the memory block, in bytes. size_t is an unsigned integral type.
sizeNew has to define the entirety of the memory you want, could be smaller, could be larger!
Yes, you can also reduce memory space
Nah, why that? It takes void* as 1st parameter and returns void*
Yes, but no need to cast!
And finally, you have to tell the total memory sizeto the function.

Realloc allocation in C

Hello I try to understand how realloc works so here is my question:
Let's say that first we call malloc in order to allocate enough memory for 1 int.
int *p=malloc(sizeof(int))
then we call realloc like this:
p=realloc(p,sizeof(int)*2);
The pointer p points to memory with available space for 2 or 1+2 ints?
As mentioned in the man pages:
void *realloc(void *ptr, size_t size);
[...]
The realloc() function changes the size of the memory block pointed
to by ptr to size bytes. The contents will be unchanged in the range
from the start of the region up to the minimum of the old and new
sizes. If the new size is larger than the old size, the added memory
will not be initialized. [...]
(My emphasis). In other words, the size parameter to realloc asks for how many bytes of memory you'd like allocated in total, not the number of bytes of memory that you'd like to add.
Hope this helps!
void* realloc (void* ptr, size_t size);
Changes the size of the memory block pointed to by ptr.
The function may move the memory block to a new location (whose address is returned by the function).
The content of the memory block is preserved up to the lesser of the new and old sizes, even if the block is moved to a new location. If the new size is larger, the value of the newly allocated portion is indeterminate.
In case that ptr is a null pointer, the function behaves like malloc, assigning a new block of size bytes and returning a pointer to its beginning.
In C90 (C++98):
Otherwise, if size is zero, the memory previously allocated at ptr is deallocated as if a call to free was made, and a null pointer is returned.
In C99/C11 (C++11):
If size is zero, the return value depends on the particular library implementation: it may either be a null pointer or some other location that shall not be dereferenced.
Argument ptr:
Pointer to a memory block previously allocated with malloc, calloc or realloc.
Alternatively, this can be a null pointer, in which case a new block is allocated (as if malloc was called).
Argument size:
New size for the memory block, in bytes.
size_t is an unsigned integral type.
Return Value:
A pointer to the reallocated memory block, which may be either the same as ptr or a new location.
The type of this pointer is void*, which can be cast to the desired type of data pointer in order to be dereferenceable.
In C90 (C++98):
A null-pointer indicates either that size was zero (an thus ptr was deallocated), or that the function did not allocate storage (and thus the block pointed by ptr was not modified).
In C99/C11 (C++11):
A null-pointer indicates that the function failed to allocate storage, and thus the block pointed by ptr was not modified.
From realloc(3)
Synopsis
void *realloc(void *ptr, size_t size);
Description
The realloc() function changes the size of the memory block pointed to by ptr to size bytes.

Resources