0

コードは次のとおりです。

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
    int *p = new int[2];
    p[0] = 1;
    p[1] = 2;
    cout << *p++ << endl;
    delete p;
    return 0;
}

コンパイルできますが、ランタイムエラー「free():invalidpointer」とそれに続くメモリマップが発生します。

オペレーティングシステムubuntu10.10
コンパイラ:g ++ 4.4.3

4

3 に答える 3

6

次の配列バージョンを呼び出す必要がありますdelete

delete[] p;

編集:しかし、あなたの本当の問題は、あなたが増加していることですp
演算子は、delete割り当てられた元のポインターに対してのみ機能します。

于 2012-09-02T01:52:43.567 に答える
3

への呼び出しは、へdeleteの呼び出しによって返されるのと同じポインタを使用する必要がありますnew

コードでは、。でインクリメントpします*p++。これは、演算子の優先順位により、として解釈され*(p++)ます。このためdelete、メモリマネージャが聞いたことのないポインタを提供しています。

さらに、を使用delete[]してへの呼び出しを照合する必要がありますnew[]

そうは言っても、ここにあなたが意図したかもしれないものの推測があります:

int *p = new int[2];
p[0] = 1;
p[1] = 2;
for(int i = 0; i < 2; i++)
    cout << p[i] << endl;
delete[] p;
return 0;
于 2012-09-02T02:24:10.383 に答える
1

コードを見てください:

int *p1 = new int;
int *p2 = new int[2];

int *p3 = p1;
int *p1 = p2;

delete p3;
delete[] p1;

ポインタp1p2は、同じ表現と同じ許可された操作のセットを持っています。コンパイラーの場合、それらは両方ともint*です。

全体として、彼らが指しているオブジェクトは大きく異なります。at hegative offsetのオブジェクトnew int[2]には、配列内のアイテムの数を含むヘッダーがあります。

配列オブジェクトの操作は、スカラーオブジェクトの場合と同じです。このオブジェクトが解放された場合にのみ、それがどのようなオブジェクトであるかをコンパイラーに通知する必要があります。単純なオブジェクトまたは配列。これは、バグと混乱の既知の原因です。それにもかかわらず、言語は数十年前にこのように定義されており、これを変更することはできません。

deleteで返されたものとまったく同じポインタを使用することも重要newです。このルールは、simplenewと。の両方に適用されnew[]ます。

于 2012-09-02T02:25:45.370 に答える