C++ memory pool with char array - c++

I just have a quick question regarding how a char array works in regards to a memory pool and allocating pointers of other variable types to it. I am working on an assignment which uses a char array for a memory pool and I need to be able to allocate pointers to it, and I have read some info on the subject but am not quite understanding one part which is how the actual allocation works such as:
const int poolSize = 60000;
char pool[poolSize];
void* allocate(int aSize)
{
//.....
return ((void*) 0);
}
long* pointer;
pointer = (long *) allocate(sizeof(long));
*pointer = 0xDEEDEEEF;
I just don't quite get exactly how this works since a char is 1 byte while a long should be 4 and so how does something like this work when I need to allocate 4 spots in the array to the one long pointer variable? Also feel free to give examples and explanations but please don't give away how the entire program should work as I would like to figure it out myself once I understand exactly how this part works. Thanks

Memory allocation is independent of type i.e whether it is long/char.etc But thing is, it is quantified on "bytes". And char is the only data type which takes one byte memory.
Its on your program how you treat the allocated memory. For ex
char s[4]={0,0,0,'A'};
int *p = (int*)s; //treating those 4 bytes as int
printf("%d",*p); //will print 65
I will suggest you to watch first 4-5 Stan-Ford Programming Paradigm lectures. Memory allocation is explained incredibly well in those lectures. You can also refer to Chapter 8 of The C programming language -by Denis Ritchie

Related

How Dynamic memory allocation allocates memory during run time ?

int a[10];
The above code will create a array of four int variable sizes & thus the programme will be able to store only 4 integers.
Now consider the following commands
int *a,*b,*c,*d;
a= (int *)malloc(sizeof(int));
b= (int *)malloc(sizeof(int));
c= (int *)malloc(sizeof(int));
d= (int *)malloc(sizeof(int));
The above part of code will create four int type pointer & will allocate them memory of int size.
I learnt that dynamic memory allocation allocates memory at rum time.
I want to know that irrespective of using array or malloc(dynamic memory allocation), the user will be getting only four int sized space to store.If we rule out that it is a pointer variable with int size memory, then what will be the use of dynamic memory allocation.In both cases , the user will get only four int spaces & to get more he will need to access the source code.So why do we use malloc or dynamic memory allocation ?
Consider
int a,*b;
cin >> a;
b= (int *)malloc(a*sizeof(int));
The user types a number a and gets a ints. The number a is not known to either to programmer or the compiler here.
As pointed out in the comments, this is still bad style in C++, use std::vector if possible. Even new is still better than malloc. But i hope the (bad) example helps to clarify the basic idea behind dynamic memory allocation.
You're right that it's all just memory. But there is a difference in usage.
In the general case, you don't necessarily know ahead of time the amount of memory you will need and then time when such memory can be safely released. malloc and its friends are written so that they can keep track of memory used this way.
But in many special cases, you happen to know ahead of time how much memory you will need and when you will stop needing it. For example, you know you need a single integer to act as a loop counter when running a simple loop and you'll be done with it once the loop has finished executing. While malloc and its friends can still work for you here, local variables are simpler, less error prone and will likely be more efficient.
int a[10];
The above line of code will allocate an array of 10 int's of automatic storage duration, if it was within a local scope.
int *a,*b,*c,*d;
The above, however, will allocate 4 pointers to int also of automatic storage duration, likewise if it was within a local scope.
a= (int *)malloc(sizeof(int));
b= (int *)malloc(sizeof(int));
c= (int *)malloc(sizeof(int));
d= (int *)malloc(sizeof(int));
And finally, the above will allocate int variable per each pointer dynamically. So, every pointer of the above will be pointing to a single int variable.
Do note that dynamically allocated memory can be freed and resized at runtime unlike static memory allocation. Memory of automatic storage duration are freed when run out of scope, but cannot be resized.
If you program in C, casting the result of malloc is unnecessary.
I suggest you to read this: Do I cast the result of malloc?
Then what your doing in your code with the 4 pointers is unnecessary; in fact you can just allocate an array of 4 int with one malloc:
int *a;
a = malloc(4 * sizeof(int));

How to know if two C-strings point to one memory block?

I have an array allocated with malloc:
char *aStr1 = (char* ) malloc (10);
And then I filled this memory:
strcpy(aStr1, "ABCDEFGHI");
After that I created a new pointer aStr2:
char *aStr2 = aStr1 + 5;
And i set fourth element of memory to '\0':
*(aStr1 + 4) = '\0';
And finally, using these two pointers in a simple function:
int checkMem(char *aStr1, char *aStr2);
This function returns true (some none zero value) if aStr1 and aStr2 pointed to one memory block, and returns zero in another case.
How i can implement this function? (I read many linux mans about allocs function and haven't found any information about such problem).
//Added
I need this to do something like that:
char *aStr1 = (char *) malloc (10);
char *aStr2 = aStr1 + 5;
strcpy(aStr1, "ABCDEFGHI");
*(aStr1 + 4) = '\0';
and than:
my_strcat(aStr1, aStr2);
I do not ask for help to implement my_strcat, but maybe, get some hint how i can resolve its problem
//Updated
thanx, for all. I solved it.
Without any low level functions you cannot correctly know, how many memory allocate (maybe on some platform or realization you can do this:
size_t ptr_size = *((size_t *)ptr - 1);
but maybe not for all it will be correct).
And solving is simple: i create local copy of aSrc2, then realloc aSrc1 and copy aSrc2 to new aSrc1.
Unfortunately you cannot tell if two pointers point to memory that belonged to the same initial allocation.
You can create classes/structures that, for instance, save the initial allocation and then you could compare them.
But without added information, you simply cannot tell.
There is no provided standard mechanism for doing this, its up to you to track the memory you received and how big those allocations are, so you'd probably want to provide your own malloc wrapper that tracks what's allocd. Store the pointers in a map so you can use lower_bound to find the nearest allocate to the first string and then check if the second string is in the same allocation.

why does this fail

i am stuck and unable to figure out why this is the following piece of code is not running .I am fairly new to c/c++.
#include <iostream>
int main(){
const char *arr="Hello";
const char * arr1="World";
char **arr2=NULL;
arr2[0]=arr;
arr2[1]=arr1;
for (int i=0;i<=1;i++){
std::cout<<arr2[i]<<std::endl;
}
return 0;
}
where as this is running perfectly fine
#include <iostream>
int main(){
const char *arr="Hello";
const char * arr1="World";
char *arr2[1];
arr2[0]=arr;
arr2[1]=arr1;
for (int i=0;i<=1;i++){
std::cout<<arr2[i]<<std::endl;
}
return 0;
}
Why is this? and generally how to iterate over a char **?
Thank You
char *arr2[1]; is an array with one element (allocated on the stack) of type "pointer to char". arr2[0] is the first element in that array. arr2[1] is undefined.
char **arr2=NULL; is a pointer to "pointer to char". Note that no memory is allocated on the stack. arr2[0] is undefined.
Bottom line, neither of your versions is correct. That the second variant is "running perfectly fine" is just a reminder that buggy code can appear to run correctly, until negligent programming really bites you later on and makes you waste hours and days in debugging because you trashed the stack.
Edit: Further "offenses" in the code:
String literals are of type char const *, and don't you forget the const.
It is common (and recommended) practice to indent the code of a function.
It is (IMHO) good practice to add spaces in various places to increase readability (e.g. post (, pre ), pre and post binary operators, post ; in the for statement etc.). Tastes differ, and there is a vocal faction that actually encourages leaving out spaces wherever possible, but you didn't even do that consistently - and consistency is universially recommended. Try code reformatters like astyle and see what they can do for readability.
This is not correct because arr2 does not point to anything:
char **arr2=NULL;
arr2[0]=arr;
arr2[1]=arr1;
correct way:
char *arr2[2] = { NULL };
arr2[0]=arr;
arr2[1]=arr1;
This is also wrong, arr2 has size 1:
char *arr2[1];
arr2[0]=arr;
arr2[1]=arr1;
correct way is the same:
char *arr2[2] = { NULL };
arr2[0]=arr;
arr2[1]=arr1;
char **arr2=NULL;
Is a pointer to a pointer that points to NULL while
char *arr2[1];
is an array of pointers with already allocated space for two items.
In the second case of the pointer to a pointer you are are trying to write data in a memory location that does not exist while in the first place the compiler has already allocated two slots of memory for the array so you can assign values to the two elements.
If you think of it very simplistically, a C pointer is nothing but an integer variable, whose value is actually a memory address. So by defining char *x = NULL you are actually defining a integer variable with value NULL (i.e zero). Now suppose you write something like *x = 5; This means go to the memory address that is stored inside x (NULL) and write 5 in it. Since there is no memory slot with address 0, the the entire statement fails.
To be honest it;s been ages since I last had to deal with such stuff however this little tutorial here, might clear the motions of array and pointers in C++.
Put simply the declaration of a pointer does NOT reserve any memory, where as the declration of a array doesn't.
In your first example
Your line char **arr2=NULL declares a pointer to a pointer of characters but does not set it to any value - thus it is initiated pointing to the zero byte (NULL==0). When you say arr2[0]=something you are attempting to place a valuei nthis zero location which does not belong to you - thus the crash.
In your second example:
The declaration *arr2[2] does reserve space for two pointers and thus it works.

Memory Fragmentation in C++

I want to use malloc()/new to allocate 256KB memory to variable m.
Then, use m to store data such as strings and numbers.
My problem is how to save data to m and retrive them.
For example, how to store int 123456 in offsets 0 to 3 and read it to variable x?
Or store "David" string from offset 4 to 8(or 9 with \0) and then, retrive it to variable s?
You can store an integer by casting pointers.
unsigned char *p = new unsigned char[256 * 1000];
*(int *) p = 123456;
int x = *(int *) p;
This is a terrible idea. Don't worked with untyped memory, and don't try to play fast and loose like you do in PHP because C++ is less tolerant of sloppy programming.
I suggest reading an introductory C++ textbook, which will explain things like types and classes which you can use to avoid dealing with untyped memory.
Edit: From the comments above, it looks like you want to learn about pointer arithmetic.
Don't use pointer arithmetic*.
* unless you promise that you know what you are doing.
Please read my comment, I think you need to know more about C and low level native programmng.
Is there a specific application for that format?
to assign a structure to memory you can do somethinglike
struct my_format{
int first;
char second[5];
};
int main()
{
struct my_format *mfp=
malloc(sizeof(struct my_format));
mfp->first=123456;
free(mfp);
}
or whatever this doesn't deal with memory specifics (IE exact positions of vars) vur doing so is just plain bad in almost all ways.

Am I using new operator correctly?

I have the following pointer.
char **x = NULL;
x is will point to an array of pointers. So is the following code correct?
x = new (nothrow) (*char)[20];
and we will dealocate it using
delete[] x;
Is
x = (char **) malloc(sizeof(char **) * 20);
and
x = new (nothrow) (*char)[20];
equivalent?
Apart from the pointer-syntax mentioned by unwind, it is equivalent: an array of 20 char* will be allocated and deleted in both cases.
C++-adept warning: use std::vector< std::string > instead :) No memory management needed.
No, that code has syntax errors. The asterisk goes after the type name, to form a pointer to that type. So it's:
char*
not:
*char
It's weird that you have this right in the "C-style" example using malloc(), but not in C++.
As many commenters have kindly enough pointed out, there are other issues with the malloc() and its use of sizeof, though. But at least it got the type name right. Personally I'm against repeating type names in malloc() calls if at all possible, so I would write that version like this, to allocate a dynamic array of 20 character pointers:
char **x;
x = malloc(20 * sizeof *x);
This way:
Should be read as "20 times the size of whatever x points at", i.e. 20 times the size of a single char * pointer.
Contains the magical constant 20 in one place only.
Doesn't repeat any part of the type, if you were to change to wchar_t **x this would still work, and not by chance.
Is written in C, since I felt that is more natural when discussing malloc(). In C++, you need to cast the return value. In C, you should never do that.
New was introduced in C++. Malloc is C.
You shouldnt mix and match them... i.e. dont use delete on something you have used malloc on. Check this article.
I'd question why you are allocating such a thing in the first place. In C++, a std::vector of std::string is much more likely to be what you need.