I'm trying to create a memory allocation system, and part of this involves storing integers at pointer locations to create a sort of header. I store a couple of integers, and then two pointers (with locations to the next and prev spots in memory).
Right now I'm trying to figure out if I can store the pointer at a location that I could later use as the original pointer.
int * header;
int * prev;
int * next;
...
*(header+3) = prev;
*(header+4) = next;
Then later...
headerfunction(*(header+4));
would perform an operation using the pointer to the 'next' location in memory.
(code for illustration only)
Any help or suggestions greatly appreciated!
Don't do direct pointer manipulation. Structs were made to eliminate the need for you to do that directly.
Instead, do something a bit more like this:
typedef struct
{
size_t cbSize;
} MyAwesomeHeapHeader;
void* MyAwesomeMalloc(size_t cbSize)
{
MyAwesomeHeapHeader* header;
void* internalAllocatorPtr;
size_t cbAlloc;
// TODO: Maybe I want a heap footer as well?
// TODO: I should really check the following for an integer overflow:
cbAlloc = sizeof(MyAwesomeHeapHeader) + cbSize;
internalAllocatorPtr = MyAwesomeRawAllocator(cbAlloc);
// TODO: Check for null
header = (MyAwesomeHeapHeader*)internalAllocatorPtr;
header->heapSize = cbSize;
// TODO: other fields here.
return (uint8_t*)(internalAllocatorPtr) + sizeof(MyAwesomeHeapHeader);
}
What-ever you are doing is not safe because you are trying to write a memory location which is not pointed by header as *(header+3) it will try to write to some other memory location 12 byte far from header pointer & if this newly memory is held by another variable then it will cause problem.
You can do as first of all allocating a big memory & then the start address will give you the source of your memory in which you can use some starting bytes or memory for controlling other parts of the remaining memory with the help of structures.
Akp is correct, just looking at what you are trying to accomplish in your code segment, if you are trying to store integer pointers in header, header should be defined as such:
int **header;
and then memory should be allocated for it.
With regards to the actual memory allocation, if on a Unix machine, you should look into the brk() syscall.
You are building a memory allocation system, and thus we assume you have a trunk of memory somewhere you can use freely to manage allocations and freeings.
As per your question, the header pointer is allocated in the heap memory (by the compiler and libraries) - and you may wonder if it is safe to use that memory since you are allocating memory. It depends on your system, and if there is another (system) memory allocation management.
But what you could do is
main() {
void *header;
void *prev;
void *next;
manage_memory_allocations(&header, &prev, &next); // never returns
}
In this case, the pointers are created on the stack - so the allocation depends on the memory where the processor stack points to.
Note the "never returns" as the memory is "freed" as soon as main ends.
Related
I am putting together a project in C where I must pass around a variable length byte sequence, but I'm trying to limit malloc calls due to potentially limited heap.
Say I have a struct, my_struct, that contains the variable length byte sequence, ptr, and a function, my_func, that creates an instance of my_struct. In my_func, my_struct.ptr is malloc'd and my_struct is returned by value. my_struct will then be used by other functions being passed by value: another_func. Code below.
Is this "safe" to do against memory leaks provided somewhere on the original or any copy of my_struct when passed by value, I call my_struct_destroy or free the malloc'd pointer? Specifically, is there any way that when another_func returns, that inst.ptr is open to being rewritten or dangling?
Since stackoverflow doesn't like opinion-based questions, are there any good references that discuss this behavior? I'm not sure what to search for.
typedef struct {
char * ptr;
} my_struct;
// allocates n bytes to pointer in structure and initializes.
my_struct my_func(size_t n) {
my_struct out = {(char *) malloc(n)};
/* initialization of out.ptr */
return out;
}
void another_func(my_struct inst) {
/*
do something using the passed-by-value inst
are there problems with inst.ptr here or after this function returns?
*/
}
void my_struct_destroy(my_struct * ms_ptr) {
free(ms_ptr->ptr);
ms_ptr->ptr = NULL;
}
int main() {
my_struct inst = my_func(20);
another_func(inst);
my_struct_destroy(&inst);
}
I's safe to pass and return a struct containing a pointer by value as you did it. It contains a copy of ptr. Nothing is changed in the calling function. There would, of course, be a big problem if another_func frees ptr and then the caller tries to use it or free it again.
Locality of alloc+free is a best practice. Wherever possible, make the function that allocates an object also responsible for freeing it. Where that's not feasible, malloc and free of the same object should be in the same source file. Where that's not possible (think complex graph data structure with deletes), the collection of files that manage objects of a given type should be clearly identified and conventions documented. There's a common technique useful for programs (like compilers) that work in stages where much of the memory allocated in one stage should be freed before the next starts. Here, memory is only malloced in big blocks by a manager. From these, the manager allocs objects of any size. But it knows only one way to free: all at once, presumably at the end of a stage. This is a gcc idea: obstacks. When allocation is more complex, bigger systems implement some kind of garbage collector. Beyond these ideas, there are as many ways to manage C storage as there are colors. Sorry I don't have any pointers to references (pun intended :)
If you only have one variable-length field and its size doesn't need to be dynamically updated, consider making the last field in the struct an array to hold it. This is okay with the C standard:
typedef struct {
... other fields
char a[1]; // variable length
} my_struct;
my_struct my_func(size_t n) {
my_struct *p = malloc(sizeof *p + (n - 1) * sizeof p->a[0]);
... initialize fields of p
return p;
}
This avoids the need to separately free the variable length field. Unfortunately it only works for one.
If you're okay with gcc extensions, you can allocate the array with size zero. In C 99, you can get the same effect with a[]. This avoids the - 1 in the size calculation.
I've read and understand the concepts behind the binary buddies approach to memory allocation, and I'm trying to put it to work in C but I have a few implementation specific questions before I can really get started.
https://drive.google.com/file/d/0BxJX9LHXUU59OWZ6ZmhvV1lBX2M/view?usp=sharing
- This is a link to the assignment specification, my question pertains to problem 5.
The problem specifies that one call to malloc is to be made at the initialization of the allocator, and all requests for memory must be serviced using the space acquired from this call.
It's clear that the initial pointer to this space must be incremented in some way when a call to get_memory() is made, and the new pointer will be returned to the calling process. How can I increment the pointer by a specific number of bytes?
I understand that free lists for each block size must be kept, but I'm unsure exactly how these will be initialized and maintained. What is stored in the free list exactly? The memory pointer?
I apologize if these questions have been asked before, I haven't found a relevant question that provided enough clarity for me to get working.
For your first question, you just have to increment your pointer like a normal variable.
The value of a pointer corresponds to the address in memory of the data it points to. By incrementing it by, say 10, you actually move 10 bytes further into your memory.
As for the free list, malloc() creates a structure contingent with the allocated memory block containing informations such as the address of the memory block,its size, and whether it is free or not.
You goal is to create these structures so you can keep track of the status the different memory blocks you have allocated or free with your get_memory() and release_memory() function.
You might also find this useful : https://stackoverflow.com/a/1957125/4758798
It's clear that the initial pointer to this space must be incremented in some way when a call to get_memory() is made, and the new pointer will be returned to the calling process. How can I increment the pointer by a specific number of bytes?
When you call get_memory(), you will return a pointer to the main memory added to some offset. The word 'increment' implies that you are going to change the value of the initial pointer, which you should not do.
Here is some simple code of me subaddressing one big memory block.
#include <stdlib.h>
#include <stdio.h>
int main (void)
{
// Allocate a block of memory
void * memory_block = malloc (512);
// Now "Split" that memory into two halves.
void * first_half = memory_block;
void * second_half = memory_block + 256;
// We can even keep splitting...
void * second_first_half = second_half;
void * second_second_half = second_half + 128;
// Note that this splitting doesn't actually change the main memory block.
// We're just bookmarking locations in it.
printf ("memory_block %p\n", memory_block);
printf ("first_half %p\n", first_half);
printf ("second_half %p\n", second_half);
printf ("second_first_half %p\n", second_first_half);
printf ("second_second_half %p\n", second_second_half);
return 0;
}
I understand that free lists for each block size must be kept, but I'm unsure exactly how these will be initialized and maintained. What is stored in the free list exactly? The memory pointer?
At a minimum, you probably want to keep track of the memory pointer and the size of that memory block, so something like this...
typedef struct memory_block {
void * memory;
size_t size;
} memory_block_t;
There are other ways to represent this though. For example, you get equivalent information by keeping track of their memory offsets relative to the global malloc. I would suggest treating memory as a set of offsets like this:
void * global_memory; // Assigned by start_memory()
// Functionally equivalent to the above struct
// memory = global_memory + begin;
// size = end - begin;
typedef struct memory_block {
size_t begin;
size_t end;
} memory_block_t;
There are multiple approaches to this difficult problem.
What is the difference between these two approaches in terms of data visibility and memory overhead (any other differences would be great as well):
Passing a local struct by reference
Passing a pointer to the allocated memory
typedef struct student_data_t_ {
char name[30];
int score;
} student_data_t;
void fill_values (student_data_t *data) {
snprintf(data->name, 30, "Howard");
data->score = 20;
return;
}
int main (void) {
student_data_t record;
student_data_t *ptr = NULL;
fill_values(&record); // <1> passing the struct by reference
ptr = (student_data_t *)malloc(sizeof(student_data_t));
if (!ptr) {
printf("NOMEM");
return 0;
}
fill_values(ptr); // <2> passing after allocating memory
if (ptr) {
free(ptr);
}
return 0;
}
For a local variable the memory overhead will exist entirely in the stack for that thread. If you use a large structure in say an embedded system, this can become a concern, as you risk a stack overflow. Generally you will use only the number of bytes requested, but stack space can be limited. (Some applications I work in have a stack of 512 bytes or less)
In the case of using malloc, you are allocating memory from the heap. This avoid the stack size concerns, but adds the requirement that you free the memory when you are done.
Visibility is determined by the variable you store the pointer in.
It is very dangerous to pass a local variable to a seperate thread, and can lead to undefined behavior if the local variable becomes invalid, say due to the function returning.
Passing a local structure is bound to be faster, the program can do groovey things at compilation time. From a machine code point of view, a local structure is effectively a constant memory address.
When you start to use malloc there is bound to be a processing overhead, there is also a space issue. Although both structures are the same malloc will probably "use" more memory than sizeof(struct) just to store the data. malloc also reserves space on every page to maintain and memory address size allocated memory lookup table, this allows free to only need an address as paramaters.
One of the biggest issues is development time introduction malloc and free to programs increases the chance of bugs, especially segmentation faults. Without mentioning the hard to track down "invisible " bug of a memory leak.
But using malloc and calloc is the only way to deal with user input, you never know how much data they're gonna enter, a text input buffer of say 2kb can easily over fill with a call to fgets
This question already has answers here:
How does free know how much to free?
(11 answers)
Closed 9 years ago.
we allocate memory dynamically in C using malloc() and we receive a pointer to a location in the heap.
now we use free() to deallocate the memory, passing the same pointer value as its argumnet.
the Question now is how does free() know how much to deallocate.. considering the fact that we can always resize the memory block allocated by malloc().
is there anything related to Hash Tables here?
A typical implementation will store information just before the address returned by malloc. That information will include the information that realloc or free needs to know to do their work, but the details of what exactly is stored there depends on the implementation.
The original technique was to allocate a slightly larger block and store the size at the beginning, a part the application didn't see. The extra space holds a size and possibly links to thread the free blocks together for reuse.
There are certain issues with those tricks, however, such as poor cache and memory management behavior. Using memory right in the block tends to page things in unnecessarily and also create dirty pages which complicate sharing and copy-on-write.
So a more advanced technique is to keep a separate directory. Exotic approaches have also been developed where areas of memory use the same power-of-two sizes.
In general, the answer is: a separate data structure is allocated to keep state.
A simplist implementation is the one in the famous K&R C Bible,page 186 - 188.
The memory block we get actually is more (a struct head's or a union head's size) than we apply for.The struct may be like this:
typedef long Align;
union header
{
struct
{
union header* ptr; // next block
unsigned size; // size of this block , times of head size
}s;
Align x;
};
A figure to demonstrate it:
When we call the free function, the behaviour may be like this:
void free(void* ptr)
{
Header *bp, *p;
bp = (Header *)ptr - 1;
/* ..... */
/*return the memory to the linked list */
}
In visual studio, we have two models: release version and debug version,we could even use
the head to store debug message to make debug easier.The header in debug version is called _CrtMemBlockHeader, the definition is as below :
typedef struct _CrtMemBlockHeader
{
struct _CrtMemBlockHeader * pBlockHeaderNext;
struct _CrtMemBlockHeader * pBlockHeaderPrev;
char * szFileName;
int nLine;
size_t nDataSize;
int nBlockUse;
long lRequest;
unsigned char gap[nNoMansLandSize];
} _CrtMemBlockHeader;
Then the memory lalout is:
A memory manager uses tables to store additional data based on a pointer, sometimes right before the pointer, sometimes elsewhere. With C being very simple, the data is most likely pointer-2 or pointer-4, as int or long type. The correct details depend on the compiler.
When we use malloc ,a block will get reserve whose size will be littile more than what we have requested and in return to this malloc we get a pointer to start of this block.
AS i told you size of this block will be littile more than what exactly you needed.This extra space will be used to keep actual requested size of block,pointer to next free block and some data which checks "if you trying to access more than allocated block".
So whenever we call free using the pointer we want to deallocate, this free will search for the extra information given in the block space, Where it gets final size to deallocate.
Assume the following situation:
typedef struct {
int ID1;
int ID2;
char string[256];
} Reg;
I create an array dynamically, this structure:
Reg *myReg = (Reg*) malloc(sizeof(Reg)*100); //array of type Reg with 100 positions.
And throughout this example system, I fill this array.
There comes a certain point I do not want the pointer "myReg" point to this vector. I want him to point to NULL. And also to clear the memory space occupied by malloc I did.
question:
If I do:
free(myReg);
This will make myReg will point to NULL and release the space taken up that I've allocated?
free(myReg);
This will make myReg will point to NULL and release the space taken up
that I've allocated?
It will only release the memory. Even without reading the specs, if you look at how the free function is declared, you'll see it can't actually change what the pointer is pointing to.
/* Even if it wanted, `free` can't make `ptr` point to anything else. */
void free(void *ptr);
A call to free only free's the memory allocated and returns it to the heap. It will not set the your myReg to NULL. You must do it yourself.
One way is to write a macro as below:
#define MY_FREE(ptr) free(ptr); ptr = NULL;
Other answers are correct.
To help understanding why it must be so, consider that there may be multiple pointers pointing to this memory, or to different parts of it:
Reg *myReg = (Reg*) malloc(sizeof(Reg)*100);
Reg *myReg2 = myReg;
Reg *myReg3 = &myReg[50];
When you free myReg, all these pointers are unchanged. They point to the same piece of memory as before, but this memory must no longer be used.
You, the programmer, should set them to NULL (or just avoid using them after free).
C can't find them all and set them to NULL. More modern languages, such as Java, know how to track all the pointers to a given object, but C does nothing like this.