I have a doubt in dynamic memory allocation (malloc)
Say
ivar=(int*)malloc(1*sizeof(int));
What the above code will do?
Will it create address for allocations?
Also which is the standard way to get values in malloc? (Say i as loop variable)
scanf("%d",&ivar[i]);
OR
scanf("%d",ivar+i);
int main()
{
int *ivar;
ivar=(int*)malloc(1*sizeof(int));
printf("%u",ivar); // outputs 2510
printf("%u",&ivar);// outputs 65524
} // please explain why it is…
Thanks in advance.
The memory allocated using malloc is created in heap section of RAM.
ivar=(int*)malloc(1*sizeof(int));
The syntax for malloc is
void *malloc(size_t size);
(1*sizeof(int)) gives 4 bytes, so 4 bytes is allocated in Heap.
You cannot directly access memory of heap, so ivar pointer is used to access it.
When you write
printf("%p",ivar); // outputs 2510
printf("%p",&ivar);// outputs 65524
Both of these gives address, first one gives address of the location pointer is pointing at, second one gives address of the pointer
scanf("%d",&ivar[i]);
and
scanf("%d",ivar+i);
both are equal, so you can use either one of them.
Related
When I run the following code:
int main(int* argc, char** argv) {
int* array = malloc(5 * sizeof(int));
free(array + 3);
}
I get the error pointer being freed was not allocated. My intuition is that instead of trying to free the fourth element of array, free tried to free the thing living 3*sizeof(int) bytes after its last element. Is this correct? If so, then why does this happen? And is the behaviour resulting from the execution of this programme always predictable, or is it undefined of implementation-specific?
free expects you to use the very same address returned from malloc or otherwise anything might happen. The malloc call allocates a whole segment per call, in this case 5 int large. It doesn't make sense to free up parts of this segment, that's not how the heap works.
Heaps first allocate a segment header which is internal information that contains size etc. Then after that header, all the data. This header part isn't visible to the programmer and how it is implemented is OS and/or C library specific.
Indeed in your case you pass an address which sits 3*sizeof(int) bytes into the data part of the segment, which isn't a valid address since free needs the initial address used by malloc in order to know where the internal header of that segment starts. When you pass the wrong address to it, it might grab some other part of random data and treat that as the header. The behavior is undefined.
(You can however pass a null pointer to free() and that's guaranteed to be a no-op.)
From specification of free():
Synopsis
#include <stdlib.h>
void free(void*ptr);
Description
The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.
Thus, what you're trying to do is undefined behavior
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf
malloc allocates a block of memory.
You can only de-allocate (free) this block. You cannot free individual elements or a part of the block.
You can re-allocate (realloc) this block to make it larger or smaller.
what is the difference between these two code snippets please can someone explain?
int a [ 7 ] ;
and
int *a = malloc ( sizeof ( int ) * 7 ) ;
?
I am a beginner in coding and I have no idea and I have tried to search it in online but couldn't find
The first one will allocate memory to a at compile time generally on stack, while second one will allocate memory in run time(generally heap) that is when you execute program.
Typically, you don't have to free memory that is allocated statically, but when you allocate memory dynamically(at run time), you should free it after using it.
In the first snippet you are allocating memory for an array of 7 integers. This memory is contiguous and taken from the stack at compile time.
In the second snippet, we have allocated memory from the heap. Again of 7 integers and the pointer variable 'a' points to this block of memory.
Note that the memory allocated for both of them is same. Also, we sometimes say that an array has decayed into a pointer. To say simply, array names in a C program are (in most cases) converted to pointers. One exception is when we use the sizeof operator on an array. If a was converted to a pointer in this context, sizeof a would give the size of a pointer and not of the actual array, which would be rather useless, so in that case a means the array itself.
I wish to free blocks of memory which I don't have pointers to. In my program, I call malloc sequentially, hoping that the memory created by malloc(1), malloc(4), malloc(5) is continuous. Then I free these memory when I only have the pointer to malloc(5). But I can't think of how this can be done; I cannot simply create a pointer that reference to the address of ptr[-5] and then free 5 bytes of memory? How can this be done?
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
malloc(1);
malloc(4);
char* ptr = malloc(5);
free(ptr);
}
You cannot do what you want to do. You should not even try to do what you want to do.
Even if you work out exactly what malloc() is doing, your program would then be relying on undefined behavior. The behavior could change when a new version of the C library arrives, and your program would almost certainly fail if you compiled it using a different toolchain (switch from GNU C to Microsoft C or whatever).
Any time you allocate memory, you need to keep track of the pointer. If your program doesn't even know about the memory, there is no way to free it.
Keep track of your memory allocations. If you are designing data structures to be dynamically allocated, your design should include features to track them, such as keeping a list of addresses in a linked list or something.
If this seems like a lot of work, maybe consider using a managed language like C# or Java or Python or whatever.
free(void*)
[deallocate] A block of memory previously allocated by a call to malloc, calloc or realloc is deallocated, making it available again for further allocations.
If ptr does not point to a block of memory allocated with the above functions, it causes undefined behavior.
- http://www.cplusplus.com/reference/cstdlib/free/
There is no way.
But I can't think of how this can be done
That's because it is not possible. The blocks that you get back from malloc can come in truly arbitrary order. The only way to free a dynamically allocated block of memory is to keep a pointer to it accessible to your program. Anything else is undefined behavior.
Note: Implementations of malloc perform "bookkeeping" to figure out what kind of block you are releasing. While it is not impossible to hack into their implementation, there is no way of doing it in a standard-compliant, portable way.
You cannot create a [-5]...thing for a variety of reasons but the from a practical standpoint you have to remember that memory allocated with malloc() is coming off of the heap and not the stack so to "count" to it from somewhere else is difficult (since multiple calls to malloc are not guaranteed to be sequential).
What happens when a pointer loses its association to memory (or goes out of scope) without being freed is called a memory leak and without exhaustive techniques not readily available in C (Java's mark/sweep garbage collection for example, or mallocing the entire memory and scanning it or something) it is not possible to reclaim this memory.
So you cannot free memory in C when a pointer is not known.
First of all - as it seems you do not understand how malloc works - passing continuous numbers to malloc, won't make it allocate an array. malloc is defined as follows:
void* malloc (size_t size);
While an integer can be converted to size_t, it's still the number of bytes allocated, not the element number. If you want to allocate an array, do it as follows:
int* myDynamicArray = malloc(sizeof(int)*numberOfElements);
Then, you can access the elements by doing:
int i;
for(i=0;i<numberOfElements;i++)
printf("%d",myDynamicArray[i]);
Then, like others pointed out - you can deallocate the memory by calling the free function. free is defined as follows:
void free (void* ptr);
And you simply call it by doing:
free(myDynamicArray);
This is by no means an endorsement of what you have done, but it is possible assuming you know that the blocks were allocated continuously.
For example:
int main(){
char* ptr1=malloc(1);
char* ptr2=malloc(4);
char* ptr3=malloc(5);
// Verify that the memory is in fact continuous.
assert(ptr3==(ptr2+4));
assert(ptr3==(ptr1+5));
free(ptr3); // Frees 5 bytes at ptr3
free(ptr3-4); // Frees 4 bytes at ptr2
free(ptr3-5); // Frees 1 byte at ptr1
}
So, you if you have a pointer and know for a fact that you allocated a set of continuous bytes before it, you can simply offset the pointer with pointer arithmetic. It is highly dangerous and not recommended, but it is possible.
Edit:
I ran a test program and on my architecture, it allocated in 32 byte chunks, so ptr1+32==ptr2, and ptr2+32=ptr3. It did this for any chunks less than or equal to 24 bytes. So if I allocated 24 or less, then each ptr would be 32 bytes greater than the previous. If I allocated 25 or more, then it allocated an additional 16 bytes, making the total 48.
So, in my architecture, you'd need to be much more creative in how you generate your pointers using pointer arithmetic since it will not work as expected.
Here is an example program that works for all sizes of ptr1, ptr2, and ptr3 on my architecture.
#define ROUNDUP(number, multiple) (((number + multiple -1)/multiple)*multiple)
#define OFFSET(size) ((size < 24) ? 32 : ROUNDUP(size+8,16))
int main(int argc, char* argv[]){
char* ptr1, *ptr2, *ptr3;
int s1=atoi(argv[1]);
int s2=atoi(argv[2]);
int s3=atoi(argv[3]);
ptr1=(char*)malloc(s1);
ptr2=(char*)malloc(s2);
ptr3=(char*)malloc(s3);
fprintf(stdout, "%p %p %p\n", ptr1, ptr2, ptr3);
assert(ptr3==(ptr2+OFFSET(s2)));
assert(ptr2==(ptr1+OFFSET(s1)));
// Try to construct ptr2 from ptr3.
free(ptr3);
free(ptr3-OFFSET(s2));
free(ptr3-OFFSET(s2)-OFFSET(s1));
}
I am confused on what actually happens in memory when memset is called versus what happens when you call free.
For example I have a pointer A that points to an array of char*'s
char** A = (char**)calloc(5, sizeof(char*));
int i;
for(i=0;i<5;i++)
{
//filling
A[i] = (char*)calloc(30, sizeof(char));
scanf("%s", &A[i]);
}
now I want to reset it my char** pointer and all the elements
it points to be completely empty
memset(A, 0, 5);
or
free(A);
what is the difference?
I am somewhat new to C so please speak in layman's terms thank you
The difference is that memset actually sets the value of a block of memory, while free returns the memory for use by the operating system.
By analogy using physical things, memset(beer, 0, 6) applied to a six-pack of beer would apply the value of '0' to all six members of the array beer, while free(beer) would be the equivalent of giving the six-pack away to a friend.
The memset function sets an area of memory to the requested value. Do note that the size you provide is the number of bytes.
The free function releases the allocated memory so it can't be used anymore. Calling free doesn't usually modify the memory in any way. Using the memory after calling free leads to undefined behavior.
Both approaches are incorrect, but somewhat complementary.
memset will set the content of the buffer to the given value, 0 in your case. This will change the value of the pointers, which will cause you to lose the references to the allocated buffers (in each A[i]).
free(A) will release the buffer pointed by A, but this buffer contains pointers, and each of the buffers that is pointed by them will not be freed.
in short - memset does not free a dynamically allocated buffer, and free does not set it to zero.
A correct approach will be something like that:
for(i=0;i<5;i++)
{
// complementary to
// A[i] = (char*)calloc(30, sizeof(char));
free(A[i]);
}
// complementary to
// char** A = (char**)calloc(5, sizeof(char*));
free(A);
A = NULL; // so no one gets confused...
free deallocates the memory, which means A would still be pointing to the same memory location, which is invalid now.
memset will set the memory currently pointed to by A, to whatever you want.
memset changes the contents at the memory address. It does not alter whether the memory is allocated/deallocated.
free does not change the contents at the memory address. It deallocates the block of memory which makes it available for the program to reclaim and reuse. Therefore any pointers to this block become invalid and trying to access the memory should result in a Segfault ("if you're lucky" as my professor would say).
Use memset when you know you are going to be accessing the data at that address again. Use free when you know that the data will no longer be accessed ever again and that the program may reclaim that memory.
memset() method just replaces the x memory bytes with a given character the allocated memory which is pointed by a pointer *a;
memset(a, 'a', x);
The prototype of memset() method is:
void* memset(void*, unsigned int, int);
memset() behaves like strcpy() but the difference is that memcpy() copied the data as it is (byte), but strcpy copies the formatted string as well (so takes more time than memcpy to execute).
However, free() method just deallocates the memory space and makes it available to get occupied.
While other answers explain the difference, let me add an example when both memset() and free() will need to be used together, in a specific order:
If the malloc'ed memory region was used to store any critical/valuable information that needs to be erased to prevent others from snooping on it (say some security-related stuff like managing a password or some other crypto), you would want to first erase the contents in that memory region and then call free() on it to give away that region's control back to the OS.
Hence, just like free() is the opposite of malloc(), memset(to zero)-then-free() is the opposite of calloc().
To understand the usage of free in the C programming language I tried running this code on Ubuntu, but on running the EXE file I am receiving a SIGABRT error. Why is the program not exiting normally?
#include<stdio.h>
#include<stdlib.h>
int main()
{
int ret;
int *ptr;
ptr = (int *)malloc(sizeof(int)*10);
free(ptr);
ptr = &ret;
free(ptr);
return 0;
}
Attempting to free a pointer you didn't get from malloc (or one of its friends) causes undefined behaviour. Your second free(ptr) call attempts just that.
From the C spec, §7.22.3.3 The free function, paragraph 2:
The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.
While all the the undefined behavior answers are correct, seeing an implementation might be more helpful.
I think a very good reference to this is K&R C malloc. An explanation of how it works is in "The C Programming Langugage", Chapter 8.7.
Remember when looking at code from standard library functions in C that they have an implementation and a specification, where the implementation might have reproducible behavior that is not required by its specification.
Essentially almost all malloc implementations have a free list where they manage free memory regions in a list (or multiple lists). The free list is often handled in a way, that calling free on a memory region multiple times will put this list in an incorrect state.
Also malicious behavior can be invoked when data structures are purposefully crafted. Phrack has a dated article on how to invoke code execution when passing invalid memory to free while corrupting the freelist.
Other malloc implementations might also be worth looking at (this is an incomplete list of allocation libraries).
ptr = &ret;
free(ptr);
is the same as:
free(&ret);
ret resides on the stack, not on the heap. Attempting to free() memory that was not allocated (with malloc(), etc.) on the heap will cause undefined behavior.
The function free() only works for the memory that has been allocated on heap by malloc(). Not for the static allocation, because static allocations are automatically handled. Here is the mistake:
int ret;
ptr = &ret;
free(ptr);
You can't do this because the memory for ret is not allocated on the heap. It's in the stack and only the memory of the heap should be freed.
Your second free(ptr) is causing undefined behavior as you are attempting to free a pointer which you didn't allocate. Also note that static allocations are automatically reclaimed, so you don't require them to free it.
ptr = &ret;
free(ptr);
Here you are trying to free the local storage stack variable's memory. As per rule you should not free it. When the main() exits all local storage memory on stack always get free.
Free only works with Heap allocation memory.
There are three areas where variables may be created in a c or c++ program.
global or static variables are at fixed locations in the executable binary file.
automatic variables outside of static scope are on the stack
malloc'ed or calloc'ed variables are on the heap.
free() is the function that releases previously allocated memory on the heap. A pointer to memory on the heap is returned by malloc or similar functions. The only way to read or write that memory is via the pointer. A pointer is an address, and a pointer* is the content pointed to at that address.
In the example shown, there are two variables, defined in Main, and effectively static, and the returned value from Main, which is on the stack. Using the miniumum int, 16 bits, here's a possible memory map. In this map, the instructions start at 0, the stack starts at some non-zero value, (beginning of stack - bos) and grows by incrementing, and a heap starts at the maximum address (...FFFF, aka -1) and grows by decrememeting:
(Remember, MIN_INT is -32768, MAX_INT is 32767... the spec guarantees only 16 bits, signed)
Each byte has an address which is 'n' bits wide - 16, 32 or 64 bits, typically
-1. (start of heap, for example, 16 bit addr: 0xFFFF, 32 bit addr: 0xFFFFFFFF or 64 bit addr: 0xFFFFFFFFFFFFFFFF)
-2. (1st location down from beginning of heap. 0x...FFFE) ptr[ 9 ], at one time
-3. (2nd location down from beginning of heap. 0x...FFFD)
-4. (3rd location down from beginning of heap. 0x...FFFC) ptr[ 8 ], at one time
[snip]
-17. (16th location down from beginning of heap. 0x...FFEF)
-18. (17th location down from beginning of heap. 0x...FFEE) ptr[ 1 ], at one time
-19. (18th location down from beginning of heap. 0x...FFED)
-20 (19th location down from beginning of heap. 0x...FFEC) ptr[ 0 ], at one time
-21. (top of heap, 10 X 16 bit ints down from beginning of heap. 0x...FFEB), at one time
:
A very large range of address on 32 or 64 bit machines...
:
tos: ( Top of stack 0x...tos )
bos + ( sizeof( int ) - 1) End of int returned from Main()
bos: (beginning of stack: above static data ) Start of int returned from Mail()
togs: (top of global/static) End of "ptr"
: (size of a pointer is width of address bus... whatever it takes)
togs-(n-1): (top of global/static - (sizeof( int* ) - 1)) start of "ptr"
(togs-n) : End of "ret"
(togs-n)-1: start of "ret"
(any global stuff the compiler adds for itself, the debugger, etc.)
(end of program code)
(start of program code)
(top of non-program code)
0 (start of non-program code, 0x...0000 )
At run-time, "ptr" and "ret" are probably both start at '0', since they're fixed, static, values, read out of the file the executable binary comes from.
As the program runs, the value of "ptr" changes, first, to point into the heap, at the malloc'ed array of 10 ints: "0x...FFEC"
The call to free() doesn't change the value of ptr, its still "0x...FFEC"
Free'ing "0x...FFEC" is legit and runs without anything funny.
The assignment "ptr = &ret" sets a new value into "ptr", "(togs-n)-1", the start of "ret".
Free'ing "(togs-n)-1" causes an immediate crash because "free" checks the value of "(togs-n)-1" and it is NOT in the valid range for a heap address.
"ret" remains blank, its never set, but since its global/static, it remains at whatever it was when the linker wrote it to disk.