malloc не выделяет нужное кол-во памяти
Здраствуйте!!! По какой то причине malloc постоянно не выделяет нужное кол-во памяти. Когда я использовал маленькие значения, у меня периодически вылезала ошибка доступа к памяти. Я решил поставить большое значение. Теперь я выделяю 10000 байт, но когда инициализирую переменную EndOfStack то постоянно вылезает ошибка доступа к памяти. Я пробовал уменьшить значение (в EndOfStack вместо ((size_t)10000) я использовал ((size_t)5000)), но это не помогает. Помогите пожалуйста.
#include <malloc.h>
using namespace std;
class Stack {
private:
~Stack() {
ClearAll();
}
const size_t StackSize = 10000;
int TypeSize = sizeof(int);
int CountOfCells = 0;
void* StartOfStack = 0;
void* EndOfStack = 0;
// Stack Pointer
int* SP = 0;
void CleanMemory() {
char* vr = (char*)StartOfStack;
for (;;) {
if (vr == EndOfStack) {
break;
}
*vr = 0;
vr += 0x1;
}
}
public:
Stack(bool cleanMemory) {
StartOfStack = malloc(StackSize);
EndOfStack = ((long long*)StartOfStack + ((size_t)5000));
SP = (int*)StartOfStack;
CountOfCells = 0;
if (cleanMemory == true) {
CleanMemory();
}
}
int PushInStack(int value) {
if (SP < EndOfStack) {
SP += TypeSize;
*SP = value;
}
else if (SP == EndOfStack) {
*SP = value;
}
return 0;
}
int PopFromStack() {
int value = *SP;
if (SP > StartOfStack) {
*SP = 0;
SP -= TypeSize;
}
else if (SP == StartOfStack) {
*SP = 0;
}
return value;
}
int GetCountOfCells() {
return CountOfCells;
}
int GetValueFromStack() {
return *SP;
}
void ClearAll() {
free(StartOfStack);
TypeSize = 0;
CountOfCells = 0;
EndOfStack = 0;
SP = 0;
}
};
Ответы (2 шт):
malloc() выделяет всё как надо. Это вы выходите за пределы выделенной памяти.
Повторю за needKVAS и Harry - не используйте malloc, не выделяйте память в байтах - выделяйте в элементах, не делайте кучу приведений типов, в которых вы сами запутались.
А у вас всё просто - при вычислении EndOfStack вы выходите за границу выделенной памяти. Для примера - при выделении массива из 3 элементов какой будет последний? Последним будет StartOfStack+2, а не StartOfStack+3. А StartOfStack+3 - это уже за пределами выделенной памяти.
Кроме того, как вам написал needKVAS, с путаницей типов вы ещё и смещение вычислили неправильно (long long*)StartOfStack + ((size_t)5000) это получается в байтах StartOfStack + 5000 * 8 = 40000. Как-бы StartOfStack + 40000 это явно за пределами выделенной памяти.
Если вы уйдете от выделения памяти через malloc() и работу с указателями, то код упроститься намного. У вас останется указатель для выделения памяти, указатель на конец стека вообще не нужен и работа упрощается. И кстати - зачем деструктор приватный?
class Stack
{
private:
const size_t Capacity = 10000; // размер выделенной памяти в элементах (не байтах)
int Size = 0; // количество элементов в стеке, он же указатель на вершину стека
int* arr = nullptr;
public:
Stack() { arr = new int[Capacity]{0}; } // выделение и обнуление памяти
~Stack() { delete[] arr; }
int Push(int value) {
if(Size >= Capacity)
throw(/*....*/) // обработать ошибку - закончилось место в стеке
arr[Size] = value;
Size++;
}
int PopFromStack() {
if(Size == 0)
// обработать ошибку - нет элементов в стеке
int value = arr[Size-1];
--Size;
return value;
}
};
Кроме того, раз вы спроектировали свой класс как владельца ресурса - динамически выделяемой памяти (сами выделяете и сами освобождаете память), вам необходимо соблюдать правило Пяти, иначе будут ошибки.
const size_t StackSize = 10000; StartOfStack = malloc(StackSize);
10000 байт.
EndOfStack = ((long long*)StartOfStack + ((size_t)5000));
5000*8 = 40000 байт.
Возможно, ты хотел
EndOfStack = (char *)StartOfStack + (size_t)5000;
SP = (int*)StartOfStack;
А почему теперь int?
PS: Остальное не смотрел.