堆损坏问题咨询:排序算法计时程序报错原因与解决方法
Hey there, let's break down why you're hitting that frustrating heap corruption error and fix up your code step by step. That error message means your program is writing to memory outside the bounds of a heap-allocated buffer—let's track down exactly where that's happening, plus fix other hidden issues in your code.
1. 最直接的堆损坏原因:数组越界写入
Look at the three loops in your main function:
for (int i = 0; i <= numbers; i++) { array_1[i] = rand()%100; // 此处有警告 }
You allocated arrays of length numbers with new long int[numbers]—array indices in C++ start at 0, so the valid range is 0 to numbers-1. But your loop condition uses i <= numbers, which means when i hits numbers, you're writing to array_1[numbers]—a memory spot outside the buffer you allocated. This is exactly what the CRT is flagging as heap corruption.
The other two array-copying loops make the exact same mistake. Change all three loop conditions to i < numbers to fix this.
2. 快速排序调用参数完全错误
Your Quicksort function is defined to take start and end indices of the array:
void Quicksort (long int* array, int L, int R)
But in main, you're passing the values of the first and last array elements instead:
Quicksort(array_2, array_2[0], array_2[numbers - 1]);
For example, if your first element is 5 and last is 99, you're telling Quicksort to sort from index 5 to 99—way outside your array's bounds if numbers is smaller than 100. The correct call should pass the actual indices:
Quicksort(array_2, 0, numbers - 1);
3. Swap函数的类型不匹配问题
Your swap function uses an int variable to store a long int value:
void swap(long int* X, long int* Y) { int Z = *X; *X = *Y; *Y = Z; }
On systems where long int is larger than int (like 64-bit systems), this will truncate the value and cause data loss. Fix this by changing Z to long int:
void swap(long int* X, long int* Y) { long int Z = *X; *X = *Y; *Y = Z; }
4. 小警告的修复(不影响正确性,但更规范)
The warnings about how_long come from implicit casting between clock_t and double. You can make the cast explicit to silence the warnings (it's safer and clearer):
how_long = static_cast<double>(stop - start) / CLOCKS_PER_SEC;
Also, your Bubble Sort can be optimized—inner loop can run from n-1 down to i instead of 1, since the first i elements are already sorted. This is a performance tweak, not a fix for corruption, but it's good practice.
修复后的完整代码
#include <iostream> #include <time.h> #include <stdlib.h> void Bubble_Sort(long int* array, int n) { for (int i = 1; i < n; i++) { // Optimized inner loop: skip already sorted elements for (int j = n - 1; j >= i; j--) { if (array[j] < array[j - 1]) { long int temporary = array[j - 1]; array[j - 1] = array[j]; array[j] = temporary; } } } } void Quicksort(long int* array, int L, int R) { int pivot = array[(L + R) / 2]; int i, j; long int x; i = L; j = R; do { while (array[i] < pivot) { i++; } while (array[j] > pivot) { j--; } if (i <= j) { x = array[i]; array[i] = array[j]; array[j] = x; i++; j--; } } while (i <= j); if (j > L) { Quicksort(array, L, j); } if (i < R) { Quicksort(array, i, R); } } void swap(long int* X, long int* Y) { long int Z = *X; *X = *Y; *Y = Z; } void Selection_Sort(long int* array, int n) { int i, j, min; for (i = 0; i < n - 1; i++) { min = i; for (j = i + 1; j < n; j++) if (array[j] < array[min]) { min = j; } swap(&array[min], &array[i]); } } int numbers; clock_t start, stop; double how_long; int main() { std::cout << "Let's check which of the known sorting algorithms is the fastest. \n"; std::cout << "How many random numbers do you want to put in the test array? "; std::cin >> numbers; long int* array_1 = new long int[numbers]; long int* array_2 = new long int[numbers]; long int* array_3 = new long int[numbers]; srand(time(NULL)); // Fixed loop condition to avoid out-of-bounds access for (int i = 0; i < numbers; i++) { array_1[i] = rand() % 100; } for (int i = 0; i < numbers; i++) { array_2[i] = array_1[i]; } for (int i = 0; i < numbers; i++) { array_3[i] = array_2[i]; } std::cout << "I start sorting the given array using different algorithms. Please wait. \n"; start = clock(); Bubble_Sort(array_1, numbers); stop = clock(); how_long = static_cast<double>(stop - start) / CLOCKS_PER_SEC; std::cout << "Bubble sort sorted the given array in " << how_long << " second(s). \n"; start = clock(); // Fixed Quicksort call: pass indices instead of element values Quicksort(array_2, 0, numbers - 1); stop = clock(); how_long = static_cast<double>(stop - start) / CLOCKS_PER_SEC; std::cout << "Quicksort sorted the given array in " << how_long << " second(s). \n"; start = clock(); Selection_Sort(array_3, numbers); stop = clock(); how_long = static_cast<double>(stop - start) / CLOCKS_PER_SEC; std::cout << "Selection sort sorted the given array in " << how_long << " second(s). \n"; std::cout << "That's all! "; delete[] array_1; delete[] array_2; delete[] array_3; system("pause"); return 0; }
如何避免此类错误未来再次发生
- Always respect array bounds: Remember arrays are 0-indexed—length
Nmeans indices go from 0 toN-1. Usei < Nin loop conditions, noti <= N. - Double-check function parameters: Make sure you're passing the right type and meaning of arguments (e.g., indices vs element values for Quicksort).
- Match types properly: Avoid implicit casts between different-sized numeric types (like
long intandint)—they can cause data loss or unexpected behavior. - Take compiler warnings seriously: Most of these issues were flagged by compiler warnings—don't ignore them! They're early hints at bugs.
内容的提问来源于stack exchange,提问作者Hyziu

