Hey my dear friends,
First of all, this is a C-question, not C++ related.
In my school-project last year we had to develop an application for a µC in C.
I think it was an AVR-controller but that does not really matter.
I ran into a problem which I couldn't really solve:
My program was to large for the µC, I think it was because I used quite large buffers but I needed large buffers so I didn't slice them off.
I solved it by slicing off some functionality instead but that wasn't very pleasuring.
So now, after having all the basics in C and C++ I decided to solve the problem, or at least I wanted to come up with a solution (at least in theory).
I came up with the following:
- I don't declare the objects on the stack.
- At the beginning of the Application I create a memory buffer, in theory it should be the size of the available memory-space.
- I pass this Memory buffer to all functions per value so after leaving the function the buffer has the same size as before.
- this is only used for array types or structs because the size of fundamental types is smaller than that of a pointer most of the time.
Now the questions I have:
- I'd like to know a few flaws in this design, I'm sure you'll find some.
- How can I prevent a user from playing around with memory_ and place_?
This is the code I have
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
// api-area
#include <stdlib.h>
// never touch the members directly (how can I force that?)
typedef struct {
void* memory_;
void* place_;
} Memory;
Memory create_memory(unsigned int size)
{
Memory mem;
mem.memory_ = malloc(size);
mem.place_ = mem.memory_;
return mem;
}
void delete_memory(Memory* mem)
{
free(mem->memory_);
mem->memory_ = 0;
mem->place_ = 0;
}
void* allocate(unsigned int size, Memory* mem)
{
void* new_location = mem->place_;
mem->place_ += size;
return new_location;
}
// prevent deallocate by using scopes, I think this is not needed
// edit: this is actually quite dangerous.
// void deallocate(unsigned int size, Memory* mem)
// {
// mem->place_ -= size;
// }
// test_area
#include <stdio.h>
unsigned int max(unsigned int v1, unsigned int v2)
{
return ( (v1>v2) ? (v1) : (v2) );
}
void print_data(Memory mem)
{
unsigned int max_size = 0;
{
Memory mem2 = mem;
int* ints = allocate(5*sizeof(int), &mem2);
int i;
for(i = 0; i < 5; ++i)
ints[i] = i;
printf("%d %d %d %d %d\n", ints[0], ints[1], ints[2], ints[3], ints[4]);
max_size = max(mem2.place_ - mem2.memory_, max_size);
}
{
Memory mem2 = mem;
char* str = allocate(5*sizeof(char), &mem2);
str[0] = 'H';
str[1] = 'e';
str[2] = 'y';
str[3] = '!';
str[4] = 0;
printf("%s\n", str);
max_size = max(mem2.place_ - mem2.memory_, max_size);
}
printf("print_data: %d bytes\n", max_size);
}
void print_ints(Memory mem)
{
int* ints = allocate(5*sizeof(int), &mem);
int i;
for(i = 0; i < 5; ++i)
ints[i] = i;
printf("%d %d %d %d %d\n", ints[0], ints[1], ints[2], ints[3], ints[4]);
printf("print_ints: %d bytes\n", mem.place_ - mem.memory_);
}
void print_str(Memory mem)
{
char* str = allocate(5*sizeof(char), &mem);
str[0] = 'H';
str[1] = 'e';
str[2] = 'y';
str[3] = '!';
str[4] = 0;
printf("%s\n", str);
printf("print_str: %d bytes\n", mem.place_ - mem.memory_);
}
int main(int argc, char** argv)
{
Memory mem = create_memory(5000*sizeof(char));
print_data(mem);
print_ints(mem);
print_str(mem);
delete_memory(&mem);
return 0;
}
|
I hope you can help me improving, even if it is "just" C and not C++
Greetings,
- Gamer2015
Edit: after rereading my post it looked a bit stupid because I could just use malloc and free.
The idea behind this is that I don't have to write free every time and so I prevent memory leaks.
I also don't have to constantly allocate and free memory so it gives a little performance boost as well.
Edit 2.0: I noticed that the deallocate function is very dangerous.