簡體   English   中英

在Linux上使用g ++進行編譯時會發生C ++無效指針錯誤,而在Windows上的CLion中則不會發生

[英]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

請記住,警告是您思考中的實際邏輯錯誤。 您應該嘗試使用零警告編譯所有代碼。 或在代碼中明確確認警告並記錄下來。

注1:

您應該僅對使用new生成的變量調用delete
您只應在使用new []生成的變量上調用delete [] new []

筆記2:

在現代C ++中,在代碼中看到裸露的新建/刪除是非常不尋常的。 這不是異常安全的,因此通常包裝在一個類中。 請參閱注釋4,以處理大多數需要動態內存的情況。

注3:

動態分配的對象通常是通過智能指針控制的。 雖然通常通過std ::容器(通常是std::vector當您不確定要使用什么東西)時控制objets組。

注4:

可變長度數組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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM