malloc не выделяет нужное кол-во памяти

Рейтинг: -1Ответов: 2Опубликовано: 14.03.2023

Здраствуйте!!! По какой то причине 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;
        }
};

Кроме того, раз вы спроектировали свой класс как владельца ресурса - динамически выделяемой памяти (сами выделяете и сами освобождаете память), вам необходимо соблюдать правило Пяти, иначе будут ошибки.

▲ 0
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: Остальное не смотрел.