Allocated memory address clash - c

i don't understand how this happen. This is portion of my code..
int isGoal(Node *node, int startNode){
int i;
.
.
}
When i debug this using gdb i found out that 'i' was allocated at the memory address that have been previously allocated.
(gdb)print &node->path->next
$26 = (struct intNode **) 0xffbff2f0
(gdb) print &i
$22 = (int *) 0xffbff2f0
node->path->next has been already defined outside this function. But as u can see they share the same address which at some point make the pointer point to another place when the i counter is changed.
I compiled it using gcc on solaris platform
Any helps would be really appreciated..

The memory for i is taken from the stack, or what in C is sometimes called "automatic storage."
The contents of memory allocated from the stack are no longer valid after the function declaring that storage has returned. For example, your isGoal() function allocates stack storage for the variable i and the storage exists only until the point in time when isGoal() returns.
The reason you see the address of i, &i has already existed during your program is that the stack memory area is continually reused. Prior to what you see in gdb, you have stored the address of a stack variable in node->path->next.
To obtain memory which remains valid after the allocating function has returned, you must use malloc() and free() to obtain what is called "dynamic memory" or, sometimes, memory from the "heap."

Two possibilities:
You have compiled with optimizations and this is confusing gdb (for example i could be optimized away, so that it actually hasn't any address)
node->path doesn't point to correctly allocated memory. For example that pointer could have been set to point to an object on the stack that subsequently went out of scope.

Related

Variables and calls in a C program and its corresponding location in the Linux process address space

I'm currently learning the Linux process address space and I'm not sure where these C variables correspond in the process address space.
I know that when a function is called, a new frame is created, it'll contain local variables and other function calls etc..
What I am not sure about is the pointers that are in the frame:
I have this function:
int main(){
char *pointer1 = NULL;
char *pointer2 = (void *)0xDDDDDDDD;
pointer1 = malloc(80);
strcpy(pointer1, "Testing..");
return(0);
}
When main is called, a new frame is created.
Variables are initialized.
What I am not sure about these are the pointers, where does:
*pointer1 correspond to in the process address space - data or text section?
*pointer2 correspond to in the process address space - data or text section?
Does NULL and 0xDDDDDDDD belong to data or text section?
since pointer1 = malloc(80), does it belong to the stack section?
First of all it should be noted that the C specification doesn't actually require local variables to be stored on a stack, it doesn't specify location of automatic variables at all.
With that said, the storage for the variables pointer1 and pointer2 themselves will most likely be put on a stack by the compiler. Memory for them will be part of the stack-frame created by the compiler when the main function is called.
To continue, on modern PC-like systems a pointer is really nothing more than a simple unsigned integer, and its value is the address where it points. The values you use for the initialization (NULL and 0xDDDDDDDD) are simply plain integer values. The initialization is done just the same as for a plain int variable. And as such, the values used for initialization doesn't really exists as "data", instead they could be encoded directly in the machine code, and as such will be stored in the "text" (code) segment.
Lastly for the dynamic allocation, it doesn't change where pointer1 is stored. What is does it simply assigning a new value to pointer1. The memory being allocated is on the "heap" which is separate from any program section (i.e. it's neither in the code, data or stack segments).
As some programmer dude just said, the C spec does not state a region where automatic variables must be placed. But it is usual for compilers to grow the stack to accommodate them there. However, they might end on the .data region, and they will if they were, e.g., defined as static char *pointer1 instead.
The initialization values may or may not exist in a program region either. In your case, since the type of values is int, most architectures will inline the initialization as appropriate machine instructions instead, if instructions with appropriate inline operators are available. In x86_64, for example, a single mov/movq operation will be issued to put the 0 (NULL) or the other int in the appropriate memory location on the stack.
However, variables initialized with global scope, such as static char string[40] = "Hello world" or other initialized global variables end up on the .data region and take up space in there. Compilers may place declared, but undefined, global scoped variables on the .bss region instead.
The question since pointer1 = malloc(80), does it belong to the stack section? is ill-defined, because it comprises two things.
The value pointer1 is a value that will be saved at &pointer1. An address which, given the above consideration, the compiler may have put on the stack.
The result of malloc(80) is a value that refers to a region on the heap, a different region, dynamically allocated outside the mapped program space.
On Linux, the result of calling malloc may even create a new NULL-backed memory region (that is, a transient region that is not permanently stored on a file; although it could be swapped by the kernel).
In essence, you could think of how malloc(80) behaves, as something like (not taking free() into consideration, so this is an oversimplification):
int space_left = 0; void *last_mapping = NULL;
void *malloc(int req) {
void *result;
if (space_left < req) {
last_mapping = mmap(NULL, MALLOC_CHUNK_LENGTH, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
space_left = MALLOC_CHUNK_LENGTH;
}
space_left -= req;
result = last_mapping;
last_mapping += req;
return result;
}
The huge difference between calling malloc and mmap with MAP_PRIVATE is that mmap is a Linux System Call, which must make a kernel context switch, allocate a new memory map and reset the MMU layer for every memory chunk allocated, while malloc can be more intelligent and use a single big region as "heap" and manage the different malloc's and free's in userspace after the heap initialization (until the heap runs out of space, where it might have to manage multiple heaps).
Last section of your doubts i.e. "since pointer1 = malloc(80), does it belong to the stack section? " , I can tell you
In C, dynamic memory is allocated from the heap using some standard library functions. The two key dynamic memory functions are malloc() and free().
The malloc() function takes a single parameter, which is the size of the requested memory area in bytes. It returns a pointer to the allocated memory. If the allocation fails, it returns NULL. The prototype for the standard library function is like this:
void *malloc(size_t size);
The free() function takes the pointer returned by malloc() and de-allocates the memory. No indication of success or failure is returned. The function prototype is like this:
void free(void *pointer);
You can refer the doc
https://www.design-reuse.com/articles/25090/dynamic-memory-allocation-fragmentation-c.html

Segmentation Fault For Struct When All Values Are Non-Null

char *s = sbrk(some_num);
if (s != (char *)-1) {
some_struct = (SomeStruct *)s;
some_struct->num = 8; //num is an int [*SEG FAULT OCCURS ON THIS LINE*]
}
Debugging using gdb:
p some_struct => (SomeStruct *) 0xef7100
p some_struct->num => 0
From a previous q/a, I understand that seg faults occur when something is NULL, but in this example, some_struct, some_struct->num, and 8 are all non-NULL.
Why does the segmentation fault occur? How can I set some_struct->num to some int value?
The pointer some_struct needs to point to some valid memory. If the function some_function returns the pointer to some local volatile variable that variable will be lost when some_function exits.
To avoid segfault you could declare the local variable in some_function as static, or you could allocate the memory from heap by letting some_function call malloc. If some_function allocates the memory with malloc it will be the responsibility of the caller to make sure that the memory is later freed.
Another way to avoid segfault would be to not return the pointer to a local variable but a global variable. However, most people agree that global variables should be avoided.
It's worthwhile to become familiar with the concept of virtual memory which underlies most of modern OS's today.
Under an OS with virtual memory, every memory address (actually virtual address) is similar to telephone number in that you cannot call someone at every combination of some 10 digits.
You are supopsed to call at only those numbers listed in the telephone book.
Otherwise you'll hear "Sorry, this number is currently out of service".
Likewise, only those virtual addresses listed in the "page table" of each process (always automatically and transparently maintained by OS) are valid for the process to access.
SEGV is OS's way of saying "Sorry, this virtual address is currently out of service."
malloc (and sbrk) can basically ask OS to allocate a memory chunk of the specified size for you and to register its address to the page table.

How memory space behave after function return for local variables?

void local () {
int x = 100;
double *loc;
loc = (double *) malloc(sizeof(double)*100);
memset(rxnrun, 0x0, sizeof(double)*100);
// perform some operations
// free(loc);
return; // without doing free for loc variable
}
here, i can see what is wrong as memory leak is there for loc variable. But, what about variable x? What will happen to memory space acquired by both variable if we leave variable x as well as loc variable unattended (not free) after function return?
Will they (both variables) still acquire space?
Actually, both the x and loc variables are local function variables, and both variables are freed when the function returns.
However, loc is a pointer and the memory the pointer points to is what is not freed. It's just the memory allocated by malloc() that is not freed.
All C implementations use a call stack. So a local variable is on that stack (or in a register) and disappears when the called function returns.
In theory, C does not require any call stack. In practice, all C implementations use one.
In fact, a local variable is lost (so disappears) when the block (between braces) declaring it is exited. Actually, the slot on the call frame may be reused, or the variable sits in a register which is often reused for other means.
When coding in C you should think as if every local variable disappears when its block is exited. The compiler is free to implement that abstraction as it wants (generally, using a call stack, or keeping that variable in some register or some other area which will be reused later).
Notice that in your example both x and loc are local variables. But loc contains a pointer to a memory zone on the heap. And that zone is released by free
Read about undefined behavior, e.g.
// WRONG CODE!
int* p = 0;
{
int y = 23;
p = &y;
};
int z = *p; // undefined behavior
Here y is a local variable to the block in braces. You store its address in p. When you dereference that address to put its content into z you have an undefined behavior and the implementation can do anything (including destroying the universe, or exploding your computer) and still be conformant to the specification of C.
What happens in reality is unpredictable without knowing the specific implementation and environment. Actually, and this is bad for you, the above code might not even "fault" and something could be stored in z.
variables x and loc will be forgotten, but memory allocated by malloc will be occupied but pointer to this memory will be forgotten.
nothing good will come.

Trying to use free() to understand how it works

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.

Understanding concept of free

Tried the following code :
#include<stdio.h>
int main()
{
int *p,*q;
p = (int *)malloc(sizeof(int));
*p =10;
q = p;
printf("%u \n",p);
printf("%u \n",q);
free(p);
printf("%u \n",p);
return 0;
}
The output got is as follows :
[root#lnxdesk Tazim]# ./a.out
154804232
154804232
154804232
Why is that address inside p is still printed even if I have done free(p);?
What has free(p) done then?
I want to understand the concept of free/malloc clearly. Any help will be valuable.
free() only frees the memory on the heap. It does not change the value of your pointer. If you tried to print the memory pointed by your pointer, you'll probably get some kind of garbage.
Also, when you called free, you gave it the pointer, not the address to your pointer, so free can't change your pointer...
That's undefined behavior - once you've freed the pointer the address stored becomes invalid and you can't do anything with it - not only you can't dereference it, but you can't even printf() the pointer value.
You are printing the pointers, i.e. the address of the memory zones allocated for you ints. Freeing a memory zone with free does not set the pointer's address to 0x00 as I think you expect.
It just tells the OS that the memory zone is available again for future re-use.
If you were printing *p after free(p), you would have problems.
malloc() and its ilk reserve space in a memory storage area called the "heap" and return a pointer to that reserved area. So in your sample above p is given a pointer to, probably, a four-byte memory region that has been reserved for its use (whose address happens to be 154804232 this time around). When you do *p = 10 you are now placing the integer value 10 into the memory pointed to. When you do q = p you're now making q point to the same chunk of reserved heap memory.
free() and its ilk just unreserve the memory. When you call free() you're saying "I'm not going to use this memory anymore". All free() does is tell the memory management system that the block of memory is now available for use once again. It emphatically does not change your pointer. It just signals that the block of memory is available. After that it is up to you to ensure that you do not use that pointer again.
If you do use that pointer again it may work fine. Once. Or twice. Or a thousand times. It'll work fine, basically, until you use it after someone else claims that memory block you've said is free and does something with it. When that transpires, Bad Things Happen<tm>. Please don't make bad things happen.
Remember : a pointer is nothing but an address. Before, after your malloc, or free, it'll give you the same result. The only thing that malloc() does is reserve space at this address. The only thing that free does is release it (most probably, mark this address as usable to store other things, "cleaning" would be time consuming).
This is why putting your pointer to NULL after a free is a good idea ; because you can be sure if the pointer is connected to something or not.
free does not reassign the pointer to point to something else. In fact, the C standard
does not mention anything be done with the pointer. This is all it says in the 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 the calloc,
malloc, or realloc function, or if the
space has been deallocated by a call
to free or realloc, the behavior is
undefined

Resources