Динамическое перераспределение стековой памяти - PullRequest
3 голосов
/ 05 октября 2011

Я довольно плохо знаком с C ++ и плохо знаком с указателями. В настоящее время я работаю над стеком и пытался перераспределить память для стека, поскольку размер стека достигает вершины, однако я сталкиваюсь с проблемами. Я уже провел много исследований как по Google, так и по переполнению стека, и нашел некоторую информацию полезной, но, поскольку я так плохо знаком со стеками и C ++, у меня все еще есть проблемы. Я надеялся, что некоторые умные и умные люди, по крайней мере, смогут направить меня в правильном направлении.

сейчас ... Вот мой код.

#include <iostream>
#define STACKMAX 20
using namespace std;

template <class T> class StackTemplated {
private:
    int top;
    T   values[STACKMAX];
public:
    StackTemplated();
    void    push(T i);
    T       pop(void);
    bool    empty(void);
 }; 


template <class T> StackTemplated<T>::StackTemplated() {
    top = -1;
}

template <class T>void StackTemplated<T>::push(T i) {
if (top == STACKMAX - 1) {

    // reallocate top of stack. (this is the area I'm having issues)
    char * string1;
    string1 = (char *)calloc(STACKMAX, sizeof(char));

        if (top == STACKMAX - 1) {
            cout << "The stack didn't re-allocate.";
            exit(1);
        }

} else {
    top++;
    values[top] = i;
}
}   

 template <class T> T StackTemplated<T>::pop(void) {
if (top < 0) {
    printf("%", "Stack underflow!");
    exit(1);
} else {
    return values[top--];
}
}   

template <class T> bool StackTemplated<T>::empty() {
return (top == -1);
}

Ответы [ 3 ]

3 голосов
/ 05 октября 2011

Вот список нескольких вещей, которые я заметил:

  • STACKMAX является константой. Если вы расширяете стек, как вы будете следить за его размером в данный момент?
  • Элемент values является массивом фиксированного размера. Вы не сможете изменить его размер динамически, не изменив способ его объявления и распределения.
  • calloc() выделяет новый фрагмент памяти с указанным вами количеством байтов. Вам нужно будет как-то скопировать существующий стек в новый блок памяти и освободить предыдущий.
  • Вы выделяете только STACKMAX байтов при вызове calloc(). Вы, вероятно, захотите увеличить это значение до sizeof T, если T не является char.

Там будет много деталей, чтобы вы могли исправить, как только вы решите эти основные вопросы. Удачи.

1 голос
/ 05 октября 2011

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

Но как насчет того, чтобы мы все это забыли? Если мы работаем в c ++, давайте использовать то, что c ++ предлагает нам, чтобы сделать нашу жизнь проще. После того, как это будет сделано, попробуйте открыть вещи, если вы действительно чувствуете необходимость.

Одна из вещей, о которых я говорю, это использование calloc. Использование calloc - это плохая идея, особенно при использовании шаблонов. Проблема в том, что, поскольку calloc не имеет информации о типе, он не будет выполнять что-то столь же основное, как вызов конструктора. Конструкторы очень важны в ООП, поскольку они гарантируют неизменность объекта при его создании. Вместо этого используйте ключевое слово new[], например

values = new T[STACKMAX];

Это выделяет массив T длиной STACKMAX. Конечно, как указывает Грег, вам следует пересмотреть использование STACKMAX и использовать вместо него переменную. Кроме того, values не должен быть статическим массивом, а должен иметь тип T*.

Еще одна вещь, о которой я говорил, это то, что вы действительно пытаетесь реализовать массив, который динамически увеличивается по мере необходимости. В c ++ мы называем такую ​​структуру vector. Если вы используете вектор, весь ваш код уменьшается до

#include<iostream>
#include<vector>

using namespace std;

template<class T> class StackTemplated {
private:
    std::vector<T> vec;

public:
    StackTemplated() { } // the constructor is trivial; in fact, you can leave it out if you want
    void    push(T i);
    T       pop(void);
    bool    empty(void);
};

template<class T>
void StackTemplated<T>::push(T i) {
    vec.push_back(i);
}

template<class T>
T StackTemplate<T>::pop(void) {
    T top = vec.back();
    vec.pop_back();
    return top;
}

template<class T>
bool StackTemplate<T>::isEmpty(void) {
    return vec.size() == 0;
}

Вот и все. Это намного менее сложно, если вы можете использовать существующую структуру данных для реализации новой структуры данных.

Как только вы действительно освоитесь с тем, как работает vector (и в Интернете есть множество объяснений / документации), , а затем попробуйте реализовать эту функцию самостоятельно. Суть в том, что реализовать структуру данных намного проще, если вы точно знаете, как она должна себя вести.

0 голосов
/ 05 октября 2011

Я бы объявил ваши значения как

T* vaules;

Затем используйте new, чтобы создать его, а не calloc.Вам нужно будет отслеживать вершину стека и его размер.Как говорит Грег, когда вы увеличиваете стек, убедитесь, что вы скопировали данные и очистили старый.

...