Error in realloc but not malloc? - c++

I am having to work with someone else's code, so I am not entirely in control over what I can change but I am wondering why I am getting this error and would appreciate any suggestions. This code is in the part that I can't change but I need to make sure the part I wrote (StringRef class) works.
The error it gives me is 'Heap block at X modified at Y past requested size of 28'. If I change the existing code which is using realloc to malloc it kicks the can down the road a bit and loads a few more values into the array. Here are the lines in question. I can't include all the code as it is too extensive. Is this enough info to diagnose what I am doing wrong?
struct StringList
{
StringRef *elements;
unsigned int count;
};
.....
// Append the given StringRef to the list.
bool StringListAppend(StringList& self, StringRef p_string)
{
StringRef *t_new_elements;
t_new_elements = (StringRef *)realloc(self.elements, (self.count + 1) * sizeof(StringRef *));
if (t_new_elements == NULL)
return false;
self.elements = t_new_elements;
std::cout<<self.count<<"\n";
// Initialize and assign the new element.
StringInitialize(self.elements[self.count]);
if (!StringAssign(self.elements[self.count], p_string))
return false;
// We've successfully added the element, so bump the count.
self.count += 1;
return true;
}
vs
StringRef *t_new_elements;
t_new_elements = (StringRef *)malloc((self.count + 1) * sizeof(StringRef *));
for the line with realloc averts the problem a little further.

sizeof(StringRef *) should be sizeof(StringRef)
You could avoid this error by using this idiom:
ptr = realloc(old_ptr, n_elements * sizeof *ptr);
when the number of bytes to allocate is determined based on the type of the variable that holds the returned pointer; it doesn't require you to repeat anything and thereby introduce a discrepancy.
As to why changing realloc to malloc slightly moves the point at which the program crashes... undefined behaviour is undefined :)

Lets say you wish to allocate some memory.
You should use malloc (stores memory on heap uninitialized) or calloc(stores initializes all elements to 0).
Explained more Here!
Realloc extends the length of your allocated memory. So you need to allocate some before you can extend it. (dont neeed to, but it is good coding practice to do so) Realloc
I would suggest looking up more on memory allocation because abusing it can greatly reduce efficiency and must be treated with precaution, like: you should always free memory that you have allocated at the end of your program!

Related

Memory allocate in c++

I have a project in which I have to allocate 1024 bytes when my program starts. In C++ program.
void* available = new char*[1024];
I write this and I think it is okay.
Now my problem starts, I should make a function that receives size_t size (number of bytes) which I should allocate. My allocate should return a void* pointer to the first bytes of this available memory. So my question is how to allocate void* pointer with size and to get memory from my available.
I'm a student and I'm not a professional in C++.
Also sorry for my bad explanation.
It looks like you're trying to make a memory pool. Even though that's a big topic let's check what's the minimal effort you can pour to create something like this.
There are some basic elements to a pool that one needs to grasp. Firstly the memory itself, i.e. where do you draw memory from. In your case you already decided that you're going to dynamically allocate a fixed amount of memory. To do it properly the the code should be:
char *poolMemory = new char[1024];
I didn't choose void* pool here because delete[] pool is undefined when pool is a void pointer. You could go with malloc/free but I'll keep it C++. Secondly I didn't allocate an array of pointers as your code shows because that allocates 1024 * sizeof(char*) bytes of memory.
A second consideration is how to give back the memory you acquired for your pool. In your case you want to remember to delete it so best you put it in a class to do the RAII for you:
class Pool
{
char *_memory;
void *_pool;
size_t _size;
public:
Pool(size_t poolSize = 1024)
: _memory(new char[poolSize])
, _pool(_memory)
, _size(poolSize)
{
}
~Pool() { delete[] _memory; } // Forgetting this will leak memory.
};
Now we come to the part you're asking about. You want to use memory inside that pool. Make a method in the Pool class called allocate that will give back n number of bytes. This method should know how many bytes are left in the pool (member _size) and essentially performs pointer arithmetic to let you know which location is free. There is catch unfortunately. You must provide the required alignment that the resulting memory should have. This is another big topic that judging from the question I don't think you intent to handle (so I'm defaulting alignment to 2^0=1 bytes).
#include <memory>
void* Pool::allocate(size_t nBytes, size_t alignment = 1)
{
if (std::align(alignment, nBytes, _pool, _size))
{
void *result = _pool;
// Bookkeeping
_pool = (char*)_pool + nBytes; // Advance the pointer to available memory.
_size -= nBytes; // Update the available space.
return result;
}
return nullptr;
}
I did this pointer arithmetic using std::align but I guess you could do it by hand. In a real world scenario you'd also want a deallocate function, that "opens up" spots inside the pool after they have been used. You'd also want some strategy for when the pool has run out of memory, a fallback allocation. Additionally the initially memory acquisition can be more efficient e.g. by using static memory where appropriate. There are many flavors and aspects to this, I hope the initial link I included gives you some motivation to research a bit on the topic.

How to free a dynamically allocated memory to an array inside a struct?

I'm trying to free the memory of the allocated array inside struct _Stack, but the program keeps crashing
typedef struct _Stack
{
int top;
unsigned int capacity;
int* arr;
}_Stack;
_Stack* createStack(int capacity)
{
_Stack* stack = (_Stack*) malloc(sizeof(_Stack));
stack->capacity = capacity;
stack->top = -1;
stack->arr = (int*) malloc(sizeof(stack->capacity * sizeof(int)));
return stack;
}
I'm using this function to free the memory, but the program crashes here.
// I have a problem here.
void stack_free(_Stack* stack)
{
free(stack->arr);
free(stack);
}
Change this:
stack->arr = (int*) malloc(sizeof(stack->capacity * sizeof(int)));
to this:
stack->arr = (int*) malloc(stack->capacity * sizeof(int));
since you want the size of the array to be equal to stack->capacity * sizeof(int), and not equal to the size of that expression.
Your program must have invoked Undefined Behavior somewhere in code not shown in the question (because of the wrong size malloc'ed), that's why it crashes later.
PS: Since you use C++, consider using new instead (and delete, instead of free()).
sizeof(stack->capacity * sizeof(int)) in your call to malloc is wrong. Instead of the size of the array, it gives the size of the number used to represent the size of the array. You probably want stack->capacity * sizeof(int).
Another possible problem is that in C you should not cast the return value of malloc, since it can hide other mistakes and cause a crash. See Do I cast the result of malloc?
In C++ you will have to do it, because of the stricter type checking in C++, but it can still hide problems.
These are the problems I see with the code you have shown. However, remember that errors in malloc and free are not necessarily caused by the actual line where they are detected. If some part of your program damages the malloc system's internal data structures, for example by a buffer overrun, the problem can manifest in a much later call to malloc or free, in a completely different part of the program.

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.

Memory allocation for incremental garbage collection simulation in c++

I need to simulate an incremental garbage collection algorithm in C++ or Java. I had a doubt based on this.
As an input (stdin from keyboard), I will be asked to allocate some memory for this code. The syntax would be:
x = alloc(128KB);
My question: is it ok to use malloc for the assignment? Or is there any other way to allocate memory? I had this doubt because, the size can go up to GB for the assignment, so using malloc might not be a good idea I think.
First of all, if you want to prohibit a huge memory allocation, just check users' input value, but I'm not sure how much memory you think as a huge memory. I think you don't worry about that, because if memory allocation failed, malloc and calloc will return a NULL pointer.
Secondly, you can also use 'calloc' for this case.
void calloc(size_t num, size_t size);
'num' is mean elements' count for allocation and 'size' is, of course, the size of element. Below codes have the same result.
ar = (int *)malloc(5 * sizeof(int));
ar = (int *)calloc(5, sizeof(int));
However, if you choose 'calloc', you may manage more logically your code, since you can divide memory quantity by unit and count.
Also, if you use 'calloc', you don't need to use memset for setting memory value to zero.
'calloc' set automatically memory value to zero.
I hope this article can help you.
malloc can allocate as much memory as you wish provided you don't go past ulimits. Give the following a go to test it out:
#include <stdlib.h>
#include <string.h>
#define ONEGB (size_t)(1073741824)
int main() {
char *p;
p = malloc(ONEGB);
if (!p) {
perror("malloc");
}
else {
memset(p, 0, ONEGB);
}
return 0;
}

Writing my own memory manager class, overriding new and delete operators

I was given the assignment of making my own memory manager class, but I really have no idea where to start. My instructions are;
//1> write a memman allocation function
//2> insure the alloce functions returns unused addresses
//3> once all memman memmory is used up, subsequent alloces return NULL
//4> enable freeing of memory and subsequent reuse of those free'd regions
I've tried searching around for any guides on dealing with memory allocation, but I have not been too successful.
Here is one very, very naive idea to get you started:
char arena[1000000];
char * current = arena;
void * memman(std::size_t n)
{
char * p = current;
current += 16 * ((n + 15) / 16); // or whatever your alignment
return p;
}
All the memory is statically allocated, so you don't need any library calls to get your initial chunk of memory. We make sure to return only pointers with maximal alignment (hardcoded to 16 here, though this should be a constant like sizeof(std::maxalign_t)). This version doesn't allow for any reclamation, and it's missing the overflow checks.
For reclamation, you could try and write a free list.
As a slight variation, you could make your array be an array of maxalign_ts, which would simplify the stepping logic a bit. Or you could make it an array of uintptr_t and use the memory itself as the free list.