我试图重新创建向量类及其基本功能,但我的程序在操作过程中不断退出。当我运行调试器时,它完全执行得很好。这是我的矢量类的样子:
template<class T>
class Vector {
T* _array;
size_t _size;
size_t _capacity;
public:
Vector() : _size(0), _capacity(8), _array(new T[_capacity]) { }
~Vector() { delete[] _array; }
void _grow() {
T* tmp = _array;
size_t old_cap = _capacity;
_capacity *= 2;
_array = new T[_capacity];
for (size_t i = 0; i < old_cap; i++) {
_array[i] = tmp[i];
}
delete[] tmp;
}
void push_back(T const& item) {
if (_size == _capacity) { _grow(); }
_array[_size++] = item;
}
void pop_back() {
_size--;
}
void insert(T item, int position) {
// implement insert here
for (int i = position; i < _size-1; i++) {
_array[i+1] = _array[i];
}
_size++;
if (_size == _capacity) {
_grow();
}
_array[position] = item;
}
void remove(int position) {
// implement remove here
for (int i = position; i < _size-1; i++) {
_array[i] = _array[i+1];
}
_size--;
}
T& operator[](int index) {
// implement operator[] here
return _array[index];
}
size_t size() const {
return _size;
}
void clear() {
// implement clear here
_size = 0;
}
};
这是实际初始化类对象并调用其成员函数的代码:
template<class T>
void noisy_push_back(Vector<T>& vector, T item) {
vector.push_back(item);
std::cout << "vector.push_back(" << item << ')' << std::endl;
}
template<class T>
void print_vector(Vector<T>& vector) {
std::cout << "vector =";
for (int i = 0; i < vector.size(); i++) {
std::cout << ' ' << vector[i];
}
}
void test1() {
std::cout << "--- Test 1 output ---\n" << std::endl;
Vector<std::string> vector;
noisy_push_back<std::string>(vector, "wonder");
noisy_push_back<std::string>(vector, "yak");
print_vector(vector);
std::cout << std::endl;
noisy_push_back<std::string>(vector, "bookshelf");
noisy_push_back<std::string>(vector, "euphoria");
print_vector(vector);
}
当我正常运行程序时,它会添加“wonder”和“yak”,然后很好地打印矢量。当它尝试
push_back("bookshelf")
时,它会以 Process finished with exit code -1073741819 (0xC0000005)
退出
有什么想法吗?
我尝试在退出之前打印出向量大小,它符合预期:
size() = 2
你的编译器应该警告你这一点;如果没有,请调出警告!
Vector() : _size(0), _capacity(8), _array(new T[_capacity])
但是,您正在尝试最后初始化您的
_array
,因为您的变量是按以下顺序声明的:
T* _array;
size_t _size;
size_t _capacity;
然后
_array
将首先被初始化。 _capacity
在初始化时将是不确定的,因此你有未定义的行为。
你应该学会使用工具。首先启用警告。然后使用地址清理器查找内存错误: https://godbolt.org/z/r5EjWoce8
=================================================================
==1==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000018 at pc 0x000000406672 bp 0x7ffc3d36ce50 sp 0x7ffc3d36ce48
READ of size 8 at 0x602000000018 thread T0
#0 0x406671 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_data() const /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/basic_string.h:234
#1 0x406671 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_is_local() const /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/basic_string.h:275
#2 0x406671 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::capacity() const /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/basic_string.h:1170
#3 0x406671 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/basic_string.tcc:279
#4 0x4087f1 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/basic_string.h:1607
#5 0x4087f1 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/basic_string.h:813
#6 0x4087f1 in Vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::push_back(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /app/example.cpp:27
#7 0x4087f1 in void noisy_push_back<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(Vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) /app/example.cpp:71
#8 0x403304 in test1() /app/example.cpp:88
#9 0x402328 in main /app/example.cpp:100
#10 0x7f2a53229d8f (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: c289da5071a3399de893d2af81d6a30c62646e1e)
#11 0x7f2a53229e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: c289da5071a3399de893d2af81d6a30c62646e1e)
#12 0x402384 in _start (/app/output.s+0x402384) (BuildId: d659454d1d76514eedee496e191fc29a836621ba)
0x602000000018 is located 0 bytes after 8-byte region [0x602000000010,0x602000000018)
allocated by thread T0 here:
#0 0x7f2a53ed1ce8 in operator new[](unsigned long) (/opt/compiler-explorer/gcc-13.1.0/lib64/libasan.so.8+0xdcce8) (BuildId: 4508ebe68c8328f99c6a77c3715bff492eb1cfd5)
#1 0x402f9e in Vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::Vector() /app/example.cpp:11
#2 0x402f9e in test1() /app/example.cpp:86
SUMMARY: AddressSanitizer: heap-buffer-overflow /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/basic_string.h:234 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_data() const
Shadow bytes around the buggy address:
0x601ffffffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x601ffffffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x601ffffffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x601fffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x601fffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x602000000000: fa fa 00[fa]fa fa fa fa fa fa fa fa fa fa fa fa
0x602000000080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x602000000100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x602000000180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x602000000200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x602000000280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==1==ABORTING
请注意,堆栈帧 6-9 显示了问题所在。