我的矢量有时有效,有时则无效
My vector works sometimes and othertimes it doesn't
我正在尝试制作自己的向量,但是我遇到了以下问题:当我将_back 100次推动时,没有问题。当我推送1000时,程序不起作用
#include <iostream>
#include <stdlib.h>
#include <conio.h>
struct Exception {
static const char* out_of_range;
};
const char* Exception::out_of_range = "[Error]: Out of range";
template < typename T >
struct vector {
typedef T myType;
public:
vector() {
m_vector = (myType*) malloc ( sizeof( myType ) );
m_position = 0;
}
template < typename ... Ts >
vector(myType head, Ts ... tail) {
m_position = 0;
m_vector = (myType*) malloc( (sizeof ...( tail ) + 1) * sizeof( myType ) );
this->push_back(head);
(this->push_back(tail),...);
}
~vector() {
free(m_vector);
m_vector = NULL;
}
void push_back( myType value ) {
m_vector[ m_position ] = value;
++m_position;
m_vector = (myType*) realloc(m_vector, m_position * sizeof(myType));
}
void pop_back() {
--m_position;
m_vector = (myType*)realloc( m_vector, m_position * sizeof (myType) );
}
myType at( size_t pos ) {
try {
if (pos < m_position)
return m_vector[ pos ];
else throw Exception::out_of_range;
} catch (const char* e) {
printf("%s", e);
return (myType){};
}
}
inline myType& front() { return *m_vector; }
inline myType& back() { return *(m_vector + size() -1); }
inline myType* data() { return m_vector; }
inline myType* begin() { return m_vector; }
inline myType* end() { return (m_vector + size()); }
inline myType operator[](size_t pos) { return m_vector[ pos ]; }
inline size_t size() { return m_position; }
inline bool empty () { return (begin() == end()? true:false); }
private:
myType* m_vector;
size_t m_position;
};
这是我的主要主要使用push_back 100次:
int main() {
vector<int> v;
for(int i = 0; i < 100; ++i) v.push_back(i);
for(int i = 0; i < 100; ++i) std::cout << v[i];
}
在这里狩猎代码啊:
int main() {
vector<int> v;
for(int i = 0; i < 1000; ++i) v.push_back(i);
for(int i = 0; i < 1000; ++i) std::cout << v[i];
}
用"不工作",我想说的是,当我被push_back插入100个值时,程序向我显示了从0到99的所有值...但是当我有1000个值时(我不知道't知道为什么)该程序仅显示一个黑屏,而没有更多
考虑
的第一个呼叫void push_back(myType value) {
m_vector[m_position] = value; // Store into 0
++m_position; // set `m_position` to 1
m_vector = (myType*)realloc(m_vector, m_position * sizeof(myType)); // Allocate more space.
}
在最后一行中分配了多少空间?m_position * sizeof(myType)
。这解析为1 * sizeof(myType)
。足够1 myType
的空间。换句话说,程序已经拥有的空间相同。这没有用。
让我们看下一个push_back
void push_back(myType value) {
m_vector[m_position] = value; // Store into 1. There is no 1. Program now broken
++m_position; // set `m_position` to 2
m_vector = (myType*)realloc(m_vector, m_position * sizeof(myType)); // Allocate more space.
}
下一个push_back
将其写入无效的存储中。程序现在正式打破,没有进一步的调试。
我们如何解决此问题?
让我们忽略malloc
和家人不处理复杂的数据结构的事实,而vector
不会观察到三和五的规则。这些在其他问题中最好处理。我们如何使用realloc
进行修复?
m_vector = (myType*) realloc(m_vector, (m_position +1) * sizeof(myType));
在直接的粗糙点上平滑。但这是地狱效率低下的。每次添加都会触发一个Realloc。这确实损害了性能。总o(1)在窗口替换为o(n)的窗口,每次复制,再加上潜在非常昂贵的内存分配。 1
更糟糕的是,删除物品时会发生什么?您失去了矢量中的数量,可能会发现自己realloc
较小的缓冲区。yuck。
要正确执行此操作,首先添加m_capacity
成员以跟踪可以存储多少数据,以便我们不必重新分配所需的金额小于所需的金额。
然后,我们在尝试存储之前测试空间数量,并可能重新分配。
void push_back( myType value ) {
if (m_position >= m_capacity)
{ // need to reallocate
m_capacity *= 2;
myType * temp = (myType*) realloc(m_vector, m_capacity *sizeof(myType));
// ask for more than is needed. Reduce number of reallocations needed
// do not overwrite m_vector. realloc can fail to allocate and then where are you?
if (temp != NULL)
{
m_vector = temp;
}
else
{
// handle error. Probably throw exception. Definitely exit function
// before trying to add new element
}
}
m_vector[ m_position ] = value; // now guarantied to have space.
++m_position;
}
1 这不是完全正确的。您会发现的一件事是,提供的记忆通常并不像您要求的那样颗粒状。当程序要求X字节时,它可能会获得比X字节大的自由存储器的方便块。您曾经注意到,有时您可以在缓冲区的末端逃跑,并且该程序不会注意到并立即崩溃?这个额外的空间是原因之一。realloc
经常可以利用这一点,并一遍又一遍地使用相同的分配,从而使程序合法地查看更多。但是,您不能指望这一点。
我假设您的代码背后的想法是M_Vector应该始终能够比目前拥有更多的值。然后,您的push_back funtion是错误的,对于m_position 1。
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 枚举进程模块在有效句柄上返回无效句柄
- 为什么在引用指针时将 const 放在 & 符号的左侧有效,而在右侧则无效?
- C++14 : 2 个随机生成器 - 一个有效,另一个无效
- 使用 CMake 与其他静态库链接的静态库 - 一个有效,一个无效。为什么?
- 为什么构造函数的虚拟函数调用有时有效,但其他调用却无效
- 类外的前向声明有效,但在嵌套时无效
- 为什么第二个代码有效而第一个代码无效?
- 将文本文件读取为 const char* 有时有效,有时无效
- reinterpret_cast可以将无效的指针值转换为有效的指针值
- 为什么C++隐式转换有效,而显式转换无效?
- (C++)比较两段代码,一段有效,一段无效,无法找出区别
- 如何说一个有效或无效,即使一个是,另一个不是
- 正则表达式有效和无效的切换
- 将流定义为私有类变量似乎在Linux下有效,但在WindowsVisualStudio下无效
- 验证用户输入是否有效 [从 'char' 到 'char*' 的转换无效]
- 在C++中嵌入Python:在Python脚本中导入模块在一个函数调用过程中有效,但在另一个调用过程中无效
- 当从一个应用程序调用时,在DLL方法中创建COM接口指针是有效的,但当从另一个应用软件调用时则无效
- 为什么这个取消注释的宏在 clang 中无效,但在 msvc 中有效
- Tensorflow模型在Python中有效,但在C++中无效