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