[英]C++ Invalid Pointer error when compiling with g++ on Linux, but not in CLion on Windows
我有一個很奇怪的問題。 我編寫了一個程序,對於2到100之間的每個n值,生成兩個相同的隨機數c型數組,然后將一個傳遞給合並排序算法,然后將一個傳遞給選擇排序算法。 它每次運行10,000個測試,並針對10,000個測試中的每個n值,確定每種情況下最壞情況的操作數。 然后,它將每個n值以及合並排序算法操作的最壞情況數目和選擇排序操作的最壞情況數目寫入.csv文件。
我的問題是:在我的CLion IDE中(在Windows 10上)構建/編譯並運行代碼時,它工作得很好,並且退出代碼為0。
當我使用FTP將文件復制到linux服務器上並嘗試編譯並運行所有內容時,它可以正常編譯,但是出現有關無效指針的運行時錯誤。
我正在使用g++ -std=c++14 -Wall main.cpp SortFunctions.cpp -o program3.out
編譯代碼。
這是我的main.cpp文件:
#include <iostream>
#include <string>
#include <cstdlib> // FOR RANDOM NUMBER GENERATION
#include <ctime> // FOR SEEDING RANDOM NUMBER GENERATION
#include "SortFunctions.h"
#include <fstream>
using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::ofstream;
using std::ios;
int main() {
// CREATE ARRAYS TO STORE NUMBER OF WORSE-CASE OPERATIONS
long long int worst_case_merge_operations[99]; // 99
long long int worst_case_selection_operations[99]; // 99
// FOR ALL VALUES OF n BETWEEN 2 AND 100, INCLUSIVE
for (int n = 2; n <= 100; n++){
cout << "Trial with n = " << n << endl;
// VARIABLES TO STORE THE VALUE UNTIL ADDED TO THE ARRAY
long long int worst_num_merge_operations = 0;
long long int worst_num_selection_operations = 0;
// FOR EACH
for (int i = 1; i <= 10000; i++) {
if (i % 100 == 0){
cout << "Beginning test " << i << " of 10,000 for n = " << n << endl;
}
// CREATE ARRAYS (OF LENGTH N)TO POPULATE WITH RANDOM NUMBERS
int array1[n];
int array2[n];
// POPULATE ARRAYS WITH RANDOM NUMBERS
for (int k = 0; k < n; k++) {
// GENERATE A RANDOM INTEGER IN THE RANGE [1,1000]
int rand_num = (rand() % 1000) + 1;
// ADD THE NUMBER TO EACH ARRAY, THUS MAKING THE ARRAYS IDENTICAL
array1[k] = rand_num;
array2[k] = rand_num;
}
// CALL MERGE SORT WITH THE ARRAY, INDEX OF FIRST ELEMENT, AND INDEX OF LAST ELEMENT
long long int merge_ops = MergeSort(array1, 0, n - 1);
if (merge_ops > worst_num_merge_operations){
worst_num_merge_operations = merge_ops;
}
// CALL SELECTION SORT, COUNTING OPERATIONS
long long int selection_ops = SelectionSort(array2, n);
if (selection_ops > worst_num_selection_operations){
worst_num_selection_operations = selection_ops;
}
// NOTE: DO NOT FORGET TO DELETE THE ARRAYS/POINTERS, OTHERWISE YOU'LL HAVE A MEMORY LEAK!!!
delete[] array1;
delete[] array2;
if (i % 100 == 0){
cout << "Completed test " << i << " of 10,000 for n = " << n << endl;
}
}
// ADD WORST-CASE NUMBER OF OPERATIONS OF EACH TO THEIR REPSECTIVE ARRAY
worst_case_merge_operations[n - 2] = worst_num_merge_operations;
worst_case_selection_operations[n - 2] = worst_num_selection_operations;
}
// PERFORM FILE IO TO CSV FILE
// COLUMNS: [N] [WORST CASE MERGE] [WORST CASE SELECTION]
cout << endl << "Attempting to perform file IO" << endl;
ofstream data_file("algorithm_data.csv");
// CHECK IF FILE IS OPEN
if(!data_file.is_open()){
cout << "Unable to open data file algorithm_data.csv" << endl;
return -1;
} else {
cout << "Data file opened" << endl;
}
// WRITE HEADER ROW FOR FILE
data_file << "n,worst case merge operations,worst case selection operations" << endl;
cout << "Header row written, attempting to write data rows" << endl;
// WRITE VALUES TO THE FILE
for (int i = 0; i < 98; i++){
//WRITE N (= I+2),WORST_CASE_MERGE,WORST_CASE_SELECTION \n
data_file << i+2 << "," << worst_case_merge_operations[i] << "," << worst_case_selection_operations[i] << endl;
}
cout << "Data rows written, attempting to close the file" << endl;
// CLOSE THE FILE
data_file.close();
cout << "Data file closed" << endl;
return 0;
}
這是我的SortFunctions.cpp文件:
#include "SortFunctions.h"
#include <iostream>
using namespace std;
/*
* NOTE: MERGE SORT ALGORITHM
*/
long long int Merge(int numbers[], int i, int j, int k) {
// COUNT OPERATIONS
long long int operations = 0;
// INCREMENT OPERATIONS
operations += 1;
// ALGORITHM
int mergedSize; // Size of merged partition
int mergePos; // Position to insert merged number
int leftPos; // Position of elements in left partition
int rightPos; // Position of elements in right partition
int* mergedNumbers = nullptr;
mergePos = 0;
mergedSize = k - i + 1;
leftPos = i; // Initialize left partition position
rightPos = j + 1; // Initialize right partition position
mergedNumbers = new int[mergedSize]; // Dynamically allocates temporary array
// for merged numbers
// Add smallest element from left or right partition to merged numbers
while (leftPos <= j && rightPos <= k) {
// INCREMENT OPERATIONS
operations += 1;
if (numbers[leftPos] < numbers[rightPos]) {
mergedNumbers[mergePos] = numbers[leftPos];
++leftPos;
}
else {
mergedNumbers[mergePos] = numbers[rightPos];
++rightPos;
}
++mergePos;
}
// If left partition is not empty, add remaining elements to merged numbers
while (leftPos <= j) {
// INCREMENT OPERATIONS
operations += 1;
mergedNumbers[mergePos] = numbers[leftPos];
++leftPos;
++mergePos;
}
// If right partition is not empty, add remaining elements to merged numbers
while (rightPos <= k) {
// INCREMENT OPERATIONS
operations += 1;
mergedNumbers[mergePos] = numbers[rightPos];
++rightPos;
++mergePos;
}
// Copy merge number back to numbers
for (mergePos = 0; mergePos < mergedSize; ++mergePos) {
// INCREMENT OPERATIONS
operations += 1;
numbers[i + mergePos] = mergedNumbers[mergePos];
}
return operations;
}
long long int MergeSort(int numbers[], int i, int k) {
// COUNT OPERATIONS
long long int operations = 0;
// INCREMENT OPERATIONS
operations += 1;
//ALGORITHM
int j;
if (i < k) {
j = (i + k) / 2; // Find the midpoint in the partition
// Recursively sort left and right partitions
operations = operations + MergeSort(numbers, i, j);
operations = operations + MergeSort(numbers, j + 1, k);
// Merge left and right partition in sorted order
operations = operations + Merge(numbers, i, j, k);
}
return operations;
}
/*
* NOTE:SELECTION SORT ALGORITHM
*/
long long int SelectionSort(int numbers[], int numbersSize) {
// CREATE COUNTER
long long int counter = 0;
// INCREMENT COUNTER
counter += 1;
int i;
int j;
int indexSmallest;
int temp; // Temporary variable for swap
for (i = 0; i < numbersSize - 1; ++i) {
// INCREMENT COUNTER
counter += 1;
// Find index of smallest remaining element
indexSmallest = i;
for (j = i + 1; j < numbersSize; ++j) {
// INCREMENT COUNTER
counter += 1;
if ( numbers[j] < numbers[indexSmallest] ) {
indexSmallest = j;
}
}
// Swap numbers[i] and numbers[indexSmallest]
temp = numbers[i];
numbers[i] = numbers[indexSmallest];
numbers[indexSmallest] = temp;
}
return counter;
}
最后,我的SortFunctions.h文件:
#ifndef PROGRAM_3_SORTFUNCTIONS_H
#define PROGRAM_3_SORTFUNCTIONS_H
//code here
long long int SelectionSort(int numbers[], int numbersSize);
long long int MergeSort(int numbers[], int i, int k);
#endif //PROGRAM_3_SORTFUNCTIONS_H
我對指針還比較陌生,如果有人可以提供幫助,我將不勝感激。 我在Google上花費了一個小時,試圖找到無濟於事的解決方案。
與-Wall -Wextra -Werror
編譯
> g++ -Wall -Wextra -Werror main.cpp
main.cpp:72:13: error: cannot delete expression of type 'int [n]'
delete[] array1;
^ ~~~~~~
main.cpp:73:13: error: cannot delete expression of type 'int [n]'
delete[] array2;
^ ~~~~~~
好像您的代碼中有兩個錯誤。
由於這兩個數組都被聲明為自動變量:
int array1[n];
int array2[n];
對它們調用delete是錯誤的(自動變量永遠不應傳遞給delete)。 因此,使用delete
這兩行。
您應該能夠更新CLion,以將錯誤視為警告:
如何在CLion中啟用所有編譯器警告?
https://www.jetbrains.com/help/clion/configuring-inspection-severities.html
請記住,警告是您思考中的實際邏輯錯誤。 您應該嘗試使用零警告編譯所有代碼。 或在代碼中明確確認警告並記錄下來。
您應該僅對使用new生成的變量調用delete
。
您只應在使用new []
生成的變量上調用delete []
new []
在現代C ++中,在代碼中看到裸露的新建/刪除是非常不尋常的。 這不是異常安全的,因此通常包裝在一個類中。 請參閱注釋4,以處理大多數需要動態內存的情況。
動態分配的對象通常是通過智能指針控制的。 雖然通常通過std ::容器(通常是std::vector
當您不確定要使用什么東西)時控制objets組。
可變長度數組VLA
在技術上不是該語言的標准部分。 一些編譯器支持它們,但是通常最好使用std::vector
int array1[n]; // Non standard if n is not a compile time constant.
std::vector<int> array1(n);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.