未绑定数组-具有奇怪行为的弹出窗口 我编写了一个未绑定数组,来练习一些C++。但是popBack方法不能正常工作。我只是想粘贴我的代码,希望不会太多。代码是用gcc(MacPorts gcc47 4.7.1_1)4.7.1编译的。我希望能得到一些帮助。谢谢:)

未绑定数组-具有奇怪行为的弹出窗口 我编写了一个未绑定数组,来练习一些C++。但是popBack方法不能正常工作。我只是想粘贴我的代码,希望不会太多。代码是用gcc(MacPorts gcc47 4.7.1_1)4.7.1编译的。我希望能得到一些帮助。谢谢:),c++,data-structures,C++,Data Structures,未绑定的_数组.hpp #ifndef _unbound_array_h_ #define _unbound_array_h_ #include <iostream> namespace datastructures { template <typename T> class UnboundArray { private: int beta; int alpha; int w; int n; //T data[];

未绑定的_数组.hpp

#ifndef _unbound_array_h_
#define _unbound_array_h_

#include <iostream>

namespace datastructures
{

template <typename T>
class UnboundArray {

private:
    int beta;
    int alpha;
    int w;
    int n;

    //T data[];
    T *data;

    auto reallocate(const int size) -> void;

public:
    UnboundArray(): beta(2) {
        alpha = 4;
        w = 1;
        n = 0;
        data = new T[w];
    }

//  void pushBack(T& element);
    auto pushBack(T element) -> void;
    auto popBack() -> T;
    auto operator [](const int& b) -> T&;
};  

    template <typename T>
    auto UnboundArray<T>::pushBack(T element) -> void {
        if (n == w) {
            reallocate(beta * n);
        }
        data[n] = element;
        n++;
   }

    template <typename T>
    auto UnboundArray<T>::popBack() -> T {
        n = (n == 0) ? 0 : (n - 1);
        if ((alpha * n <= w) && n > 0) {
            reallocate(beta * n);
        }
        return data[n];
    }

    template <typename T>
    auto UnboundArray<T>::operator [](const int& b) -> T&{
        return data[b];
    }

    template <typename T>
    auto UnboundArray<T>::reallocate(const int size) -> void {
        int idx = n;
        w = size;
        T *array = new T[w];
        for (int i = 0; i < idx; ++i) array[i] = data[i];
        delete[] data;
        data = array;
        std::cout << "Reallocation. #elements: " << (n + 1) 
        << " new size of UnboundArray: " << w << std::endl;
    }

} // datastructures
#endif
#include <iostream>
#include "unbound_array.hpp"


using namespace datastructures;

int main() {
    int num = 25;

    std::cout << "Test of datastructures" <<std::endl;
    UnboundArray<int> a;
    for (int i = 0; i < num; ++i) {
        std::cout << "Adding "<< i <<" to UnboundArray." << std::endl;
        a.pushBack(i);
    }

    for (int i = 0; i < num; ++i) {
        std::cout << "array[" << i << "] = "<< a[i] << std::endl;
    }

    for (int i = 0; i < num; ++i) {
        std::cout << "Popping " << a.popBack() << std::endl;
    }

    return 0;
}
编辑

我在“重新分配”中更改了代码

template <typename T>
auto UnboundArray<T>::reallocate(const int size) -> void {
    w = size;
    T *array = new T[w];
    for (int i = 0; i < w; ++i) array[i] = data[i];
    delete[] data;
    data = array;
    std::cout << "Reallocation. #elements: " << (n + 1)
    << " new size of UnboundArray: " << w << std::endl;
}

您的
popBack
减小数组的大小,可能会重新定位,该数组使用缩小的大小进行复制,然后尝试读取旧大小的最后一个元素(未复制)。我建议您将popBack改为:

template <typename T>
    auto UnboundArray<T>::popBack() -> T {
        n = (n == 0) ? 0 : (n - 1);
        T result = data[n];
        if ((alpha * n <= w) && n > 0) {
            reallocate(beta * n);
        }
        return result;
    }
模板
自动取消绑定::popBack()->T{
n=(n==0)?0:(n-1);
T结果=数据[n];
如果((α*n0){
重新分配(β*n);
}
返回结果;
}
当对空数组调用popBack时,我还会抛出一个异常

在OPs编辑后

我提到的问题通过编辑在某些方面得到了解决,但仍然存在缺陷:
<代码>重新分配总是用“代码> betaβ*n/CODE”调用,所以内部重新分配<代码>大小=2 *N< /代码>。由于数据将持有<代码> N< /代码>元素,它将读取两倍于此的数据。这可能触发访问冲突,因此您应该认为您的代码不安全。只读取有多少(n个元素)。当然,这是理所当然的,n始终保持数组中正确的元素数,因此在调用
重新分配
之前,不能更改它。

您的
弹出式缩进
会减小数组的大小,可能会重新定位,这会使用缩小的大小进行复制,然后尝试读取旧大小的最后一个元素(未复制)。我建议您将弹出窗口更改为:

template <typename T>
    auto UnboundArray<T>::popBack() -> T {
        n = (n == 0) ? 0 : (n - 1);
        T result = data[n];
        if ((alpha * n <= w) && n > 0) {
            reallocate(beta * n);
        }
        return result;
    }
模板
自动取消绑定::popBack()->T{
n=(n==0)?0:(n-1);
T结果=数据[n];
如果((α*n0){
重新分配(β*n);
}
返回结果;
}
当对空数组调用popBack时,我还会抛出一个异常

在OPs编辑后

我提到的问题通过编辑在某些方面得到了解决,但仍然存在缺陷:
<代码>重新分配总是用“代码> betaβ*n/CODE”调用,所以内部重新分配<代码>大小=2 *N< /代码>。由于数据将持有<代码> N< /代码>元素,它将读取两倍于此的数据。这可能触发访问冲突,因此您应该认为您的代码不安全。只读取有多少(n个元素)。当然,这是理所当然的,n始终保持数组中元素的正确数量,因此在调用
重新分配
之前,不能更改它。

您应该注意,为容器使用array new会强制您的类型为默认可构造和可赋值,并导致“unused”不必要的默认构造元素。分离内存分配和对象构造(如
std::vector
does)是一项关键的设计改进。我不确定我是否理解正确,但使用C++11及其新的移动语义,这个问题不是过时了(运算符=(t&&))。我没有使用vector,因为我知道它节省了我(大脑)我想做一些事情来改善我的数据结构和C++知识。C++ 11不是魔术。我在谈论C++对象模型的基本原理。一个动态容器不应该包含比它更多的元素,但是你的版本确实有那些隐藏的元素,它们没有任何用途。一个更合适的解决方案是管理内存和对象。分别。@jim810如果答案正确,请将其标记为正确(在投票标记下方打勾),或者如果到目前为止没有解决问题的答案,请重新表述您的问题。问题是我的重新分配方法(我出界了)。我在上面的编辑中修复了它。不幸的是,没有传播这一想法的答案。您应该注意,为容器使用数组new会强制您的类型为默认可构造和可分配类型,并导致“未使用”元素不必要的默认构造。分离内存分配和对象构造(比如
std::vector
does)是一个关键的设计改进。我不确定我是否正确,但有了C++11及其新的移动语义,这个问题不是过时了吗(操作符=(t&&))。我没有使用vector,因为我知道它救了我(大脑)我想做一些事情来改善我的数据结构和C++知识。C++ 11不是魔术。我在谈论C++对象模型的基本原理。一个动态容器不应该包含比它更多的元素,但是你的版本确实有那些隐藏的元素,它们没有任何用途。一个更合适的解决方案是管理内存和对象。分别。@jim810如果答案正确,请将其标记为正确(在投票标记下方打勾),或者如果到目前为止没有解决问题的答案,请重新表述您的问题。问题是我的重新分配方法(我出界了)。我在上面的编辑中修复了它。不幸的是,没有传播该想法的答案。谢谢!…我差点忘了我的小项目。我在edit2中做了一些更改谢谢!…我差点忘了我的小项目。我在edit2中做了一些更改
template <typename T>
    auto UnboundArray<T>::popBack() -> T {
        n = (n == 0) ? 0 : (n - 1);
        T result = data[n];
        if ((alpha * n <= w) && n > 0) {
            reallocate(beta * n);
        }
        return result;
    }