在使用后,我尝试了delete
的(有些可疑)约定,但这似乎不起作用。该程序应该接收单个整数的输入,对随机创建的数组进行排序,并打印经过的时间进行排序,但是当我将delete
留在其中时,程序在我执行完操作后甚至没有警告就异常结束输入。换句话说,它崩溃了。但是,当我仅注释掉delete
行时,该程序将完美执行。
MWE正在测量一种简单的快速排序算法的时间,由于这是一个学校项目,因此我无法更改main()
函数以及使用QuickSort
类及其指针等。
我唯一可以更改的是各种函数中的内容,尽管set(double*, int)
似乎可以集成到构造函数中,但出于某些原因,这是不可能的选择。
目标是在构造函数中定义一个默认double*
,然后将其删除并将input_array
复制到this->arr
中的set
中:
编辑:我使用Windows 10和MinGw-w64的GCC C ++编译器。所有编译均已在Windows命令提示符中执行。
main.cpp
#include <iostream>
#include <cstdlib> // Just for good measure, though this shouldn't be needed
#include "Sort.hpp"
bool check_quick(QuickSort *quick_sort) {
int i = 0;
while(i < (quick_sort->size) - 1) {
if (quick_sort->arr[i] > quick_sort->arr[i + 1]) break;
++i;
} if (i == (quick_sort->size) - 1) return true;
else return false;
}
int main() {
int n; cin >> n;
double *input_array = new double[n];
srand((unsigned int)time(NULL));
for (int k = 0; k < n; k++) input_array[k] = (double)((rand() % n));
QuickSort* quick_sort = new QuickSort();
quick_sort->set(input_array, n);
quick_sort->run();
if (check_quick(quick_sort)) {
cout << "QuickSort is validated" << endl << endl;
} delete quick_sort;
}
Sort.hpp
#define CLOCKS_PER_SECOND 1000
#include <iostream>
#include <ctime>
#include <iomanip> // Use to call setprecision(4)
using namespace std;
class QuickSort {
friend bool check_quick(QuickSort*); // Give access for private variables
public:
void print_time() const {
cout << "QuickSort : " << fixed << setprecision(4) << seconds
<< " sec" << endl;
// << fixed << setprecision(4) always prints to four numbers after point
}
QuickSort() {
this->arr = new double[10];
for (int i = 0; i < 10; ++i) this->arr[i - 1] = i; // Set default array
seconds = clock(); // Set current Millisecond to starting time
}
~QuickSort() {
delete this->arr; // Delete array in object of this class
}
void sorter(double *arr, int begin, int end) { // Sorting Recursive Function
// Size of array without pivot is: end - begin
int pivot = arr[end];
// PIVOT is element at end of subarray "arr[begin...end]"
int i = begin, j = end;
while (i <= j) {
while (arr[i] < pivot) i++; // Increment until arr[i] is larger than
while (arr[j] > pivot) j--; // Decrement until arr[j] is lesser than
if (i <= j) { // If the larger element precedes lesser element
swap(arr[i], arr[j]); // Call Swap function
i++; j--;
} // If i is larger than j now, i was 1 lesser than j before,
// effectively leaving no more elements to scan.
}
if (begin < j) sorter(this->arr, begin, j); // Recursive, larger part
if (end > i) sorter (this->arr, i, end); // Recursive, lesser part
}
void run() {
sorter(this->arr, 0, this->size - 1); // Call Sorter function
seconds = (double)(clock() - seconds) / (double)(CLOCKS_PER_SECOND);
// Calculate Difference of Ticks and divide by Ticks per second.
// Now, `seconds` is passed seconds with millisecond precision.
}
void set(double *arr, int size) {
this->arr = new double[size]; // Make new array of `size` size
for (int i = 0; i < size; i++) this->arr[i] = arr[i]; // Copy input_arr
for (int i = 0; i < size; i++) cout << this->arr[i] << endl; // Copy input_arr
this->size = size; // Save global `size` to object of class
}
void swap(double &p, double &q) { // Swap Function
// Ampersand precedence to change input
double x = p; // Temporary `double` saver
p = q; // p is q
q = x; // q is x, which is p
}
private:
double *arr;
int size;
double seconds;
};
答案 0 :(得分:3)
在您的QuickSort
构造函数中,您正在写要分配的数组的边界之外:
this->arr = new double[10];
for (int i = 0; i < 10; ++i) this->arr[i - 1] = i; // Set default array
在第一次迭代中,i
是0
,因此this->arr[i - 1]
写入元素-1
。仅当您调用delete
时,它才会崩溃,就好像您没有在运行时没有注意到此损坏并干净地退出一样。
大概只是将i-1
更改为i
将产生所需的行为。
答案 1 :(得分:2)
QuickSort::set
的第一行:
this->arr = new double[size]; // Make new array of `size` size
泄漏在QuickSort
的构造函数中分配的数组。在分配delete[]
指向另一个数组之前,您需要首先arr
该数组:
delete[] arr;
this->arr = new double[size]; // Make new array of `size` size
如果这是真实世界,而不是简陋的分配,那么在这种情况下最好不要使用原始指针。相反,std::vector<double>
更合适。
答案 2 :(得分:2)
快速浏览发现您正在使用OnButtonUp
而不是delete
。
此行:
删除此-> arr; //删除此类对象中的数组
应为:
delete [] this-> arr; //删除此类对象中的数组
此外,根据删除约定,您还应该这样做:
delete [] this-> arr;
this-> arr = nullptr; //这很重要,否则您将被双重删除,这会带来麻烦。