我刚开始学习c++,为了更好地理解内存的工作原理,我尝试在c++中构建一个动态大小的数组。我成功地实现了push和get功能,但当我尝试添加pop功能时,我偶然发现了一个非常奇怪的错误,我在互联网上没有找到任何类似的记录,这是在使用delete
关键字释放内存时发生的。
下面是我的代码:
#include <iostream>
#include <cstdlib>
using namespace std;
template <class T>
class Array {
T* ptr;
public:
int size;
Array(unsigned int original_size) : size(original_size) {
ptr = (T*) malloc(size * sizeof(T));
}
Array () {
size = 0;
ptr = 0;
}
void set(int pos, T val) {
ptr[pos] = val;
}
T get(int pos) {
return ptr[pos];
}
T operator[] (int i) {
return get(i);
}
void operator() (int pos, T val) {
set(pos, val);
}
void add(T value) {
ptr = (T*) realloc(ptr, (++size) * sizeof(T));
set(size - 1, value);
}
T pop() {
T temp = get(--size);
delete (ptr + size);
return temp;
}
};
int main() {
Array<int> arr(3);
arr(0, 1);
arr(1, 2);
arr(2, 3);
arr.add(4);
arr.add(5);
cout << arr.pop();
cout << arr.pop();
}
字符串
这段代码在pop方法中调用delete命令后失败,消息是Unknown Signal
。你知道我做错了什么吗?
1条答案
按热度按时间gcmastyq1#
这里有两个问题。
1.将
delete
与malloc/realloc
一起使用1.调整
delete/free
中使用的指针当您向
Array
添加元素时,您可以使用malloc()
为初始Array
和realloc()
分配内存,并且没有问题。并将
Array
分配的内存地址存储在ptr
中。但是在
pop()
方法中,你可以像这样释放这个分配:字符串
虽然
delete
应该只与new
运算符一起使用,因为它会导致未定义的行为,但在这种特殊情况下,编译器会调用free()
。所以你基本上告诉
malloc()
释放内存,但给予了一个错误的地址:指针地址+偏移量。这个偏移量size
“损坏”了ptr
并混淆了malloc()
。你不能简单地释放/删除分配的数组的一部分。我的意思是你可以,但使用realloc()
。malloc
不知道如何处理,所以它以SIGABRT信号结束:型
基本上,你也应该在方法
pop()
中使用realloc()
,从Array
中删除元素,如下所示:型
或者你可以尝试使用
new
操作符的重新制作的例子:型
希望它能帮助你从这个答案和下面的评论中学到一些东西。