1

私は以下のような機能を持っています

int* readFile(string InputPath)
{
    int *myvar = new int[10]; //The file has 10 lines (Using heap)

    ifstream inFile;

    inFile.open(InputPath.c_str(), ios::in);

    if (inFile.fail())
    {
        cout << "Error reading the input file ";
        cout << InputPath << ".";
        exit(0);
    }
    string fileLine;

    while (getline(inFile, fileLine))
    {
       myvar[i]=toint(fileLine); //will be converted to int!
    }
    ;
    inFile.close();



    return myvar;
}:

ヒープ (myvar) を解放するにはどうすればよいですか? 一般に、そのような配列を返すための最良の方法は何ですか?

4

5 に答える 5

2

ヒープ (myvar) を解放するにはどうすればよいですか?

返される int*; 変えないで なくさないで 記憶が終わったら

delete [] theReturnedPointer;

配列にする本当に正当な理由がない限り、メモリ管理の手間を省き、ベクトルを使用することができます。

最良の方法

最良の方法は、ベクトルを返すことです。

vector<int> readFile(const string& InputPath)
{
    ifstream inFile(InputPath); // or inputPath.c_str() for old compilers
    if (!inFile)
    {
        cout << "Error reading the input file " << InputPath << ".";
        exit(0); // thow would be better! Or at least return an empty vector.
    }

    vector<int> myvar;
    for(int n; inFile >> n && myvar.size() < 10; )
    {
       myvar.push_back(n);
    }
    return myvar;
}

しかし、本当に本当に を使用したい場合はnew[]、少なくとも自己管理ポインター を返しますstd::unique_ptr<int[]>。C++ ではなく、生のポインターを関数からエスケープさせないでください。

于 2012-09-19T07:33:34.283 に答える
2

それを呼び出すことは、明らかに発信者の責任になりdelete[]ます。これは、返されたポインターが で割り当てられていることを呼び出し元が認識している必要があることを意味することに注意してくださいnew[]。これは、正確には最適ではありません。

代わりにa を返す必要がstd::vector<int>あります。これにより、すべてが非常に簡単になります。

于 2012-09-19T07:33:47.523 に答える
2

呼び出し元はdelete[]、関数から返された値を受け取る必要があります。このままのコードでは、配列の末尾を超えた書き込みに対する保護は提供されません。

while (getline(inFile, fileLine))
{
    myvar[i]=toint(fileLine); //will be converted to int!
}

ただし、これは C++ であるため、代わりに a を使用std::vector<int>int、文字列として読み取って変換を実行する代わりに、入力ストリームから直接 s を読み取ります。std::vector<int>がメモリ管理を処理します。

std::vector<int> myvar;

int i;
while (inFile >> i) myvar.push_back(i);

関数から を返しstd::vector<int>ます。呼び出し元は、戻り値に含まれる s の数を正確に知ることintができ (末尾を示すセンチネル値を含めない限り、配列を返す場合はわかりません)、明示的に削除する必要はありません。

于 2012-09-19T07:34:21.740 に答える
1

このポインターで削除を呼び出すコードが必要です。

これを行うより良い方法は、引数としてポインターを取得することだと思います。そのようにすると、誰かがこの関数を使用して配列を初期化することを余儀なくされるため、将来それを削除する必要があることがわかります。

于 2012-09-19T07:35:49.267 に答える
0

C++ の規則では、割り当てられたメモリは返されません。代わりに、関数プロトタイプは次のようになります。

size_t readFile(string InputPath,int* array,size_t n_elements);

この関数は、実際に配列に配置した要素の数を返します。呼び出し元は、必要な new/delete[] だけでなく、malloc/free または VirtualAlloc などの低レベルのシステム関数も使用して、適切なメソッドを使用してメモリの割り当てと解放を行います。

于 2012-09-19T07:40:55.610 に答える