C++ Delete关键字导致`未知信号`

6yoyoihd  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(165)

我刚开始学习c++,为了更好地理解内存的工作原理,我尝试在c++中构建一个动态大小的数组。我成功地实现了push和get功能,但当我尝试添加pop功能时,我偶然发现了一个非常奇怪的错误,我在互联网上没有找到任何类似的记录,这是在使用delete关键字释放内存时发生的。
下面是我的代码:

  1. #include <iostream>
  2. #include <cstdlib>
  3. using namespace std;
  4. template <class T>
  5. class Array {
  6. T* ptr;
  7. public:
  8. int size;
  9. Array(unsigned int original_size) : size(original_size) {
  10. ptr = (T*) malloc(size * sizeof(T));
  11. }
  12. Array () {
  13. size = 0;
  14. ptr = 0;
  15. }
  16. void set(int pos, T val) {
  17. ptr[pos] = val;
  18. }
  19. T get(int pos) {
  20. return ptr[pos];
  21. }
  22. T operator[] (int i) {
  23. return get(i);
  24. }
  25. void operator() (int pos, T val) {
  26. set(pos, val);
  27. }
  28. void add(T value) {
  29. ptr = (T*) realloc(ptr, (++size) * sizeof(T));
  30. set(size - 1, value);
  31. }
  32. T pop() {
  33. T temp = get(--size);
  34. delete (ptr + size);
  35. return temp;
  36. }
  37. };
  38. int main() {
  39. Array<int> arr(3);
  40. arr(0, 1);
  41. arr(1, 2);
  42. arr(2, 3);
  43. arr.add(4);
  44. arr.add(5);
  45. cout << arr.pop();
  46. cout << arr.pop();
  47. }

字符串
这段代码在pop方法中调用delete命令后失败,消息是Unknown Signal。你知道我做错了什么吗?

gcmastyq

gcmastyq1#

这里有两个问题。
1.将deletemalloc/realloc一起使用
1.调整delete/free中使用的指针
当您向Array添加元素时,您可以使用malloc()为初始Arrayrealloc()分配内存,并且没有问题。
并将Array分配的内存地址存储在ptr中。
但是在pop()方法中,你可以像这样释放这个分配:

  1. delete (ptr + size);

字符串
虽然delete应该只与new运算符一起使用,因为它会导致未定义的行为,但在这种特殊情况下,编译器会调用free()
所以你基本上告诉malloc()释放内存,但给予了一个错误的地址:指针地址+偏移量。这个偏移量size“损坏”了ptr并混淆了malloc()。你不能简单地释放/删除分配的数组的一部分。我的意思是你可以,但使用realloc()
malloc不知道如何处理,所以它以SIGABRT信号结束:

  1. malloc_printerr (str=str@entry=0x7ffff7d32210 "munmap_chunk(): invalid pointer") at ./malloc/malloc.c:5664


基本上,你也应该在方法pop()中使用realloc(),从Array中删除元素,如下所示:

  1. T pop() {
  2. T temp = get(--size);
  3. ptr = (T*) realloc(ptr, (size) * sizeof(T));
  4. return temp;
  5. }


或者你可以尝试使用new操作符的重新制作的例子:

  1. template<typename T>
  2. class Array {
  3. T* ptr;
  4. public:
  5. int size;
  6. Array () {
  7. cout << "Array() Constructor" << endl;
  8. size = 0;
  9. ptr = 0;
  10. }
  11. Array(unsigned int original_size) : size(original_size) {
  12. cout << "Array(size) Constructor" << endl;
  13. ptr = new T[size];
  14. }
  15. Array(T arr[], int original_size) : size(original_size) {
  16. cout << "Array(arr[], size) Constructor" << endl;
  17. ptr = new T[size];
  18. for (int i = 0; i < size; i++)
  19. ptr[i] = arr[i];
  20. }
  21. ~Array () {
  22. cout << "Array() Destructor" << endl;
  23. delete[] ptr;
  24. }
  25. T operator[] (int i) {
  26. return get(i);
  27. }
  28. void operator() (int pos, T val) {
  29. set(pos, val);
  30. }
  31. void set(int pos, T val) {
  32. ptr[pos] = val;
  33. }
  34. T get(int pos) {
  35. return ptr[pos];
  36. }
  37. void push(T value) {
  38. T* newptr = new T[++size];
  39. for (int i = 0; i < size - 1; i++)
  40. newptr[i] = ptr[i];
  41. newptr[size - 1] = value;
  42. delete[] ptr;
  43. ptr = newptr;
  44. }
  45. T pop() {
  46. T temp = get(--size);
  47. T* newptr = new T[size];
  48. for (int i = 0; i < size; i++)
  49. newptr[i] = ptr[i];
  50. delete[] ptr;
  51. ptr = newptr;
  52. return temp;
  53. }
  54. };


希望它能帮助你从这个答案和下面的评论中学到一些东西。

展开查看全部

相关问题