softya(ソフト屋) さんが書きました:
newでの配列確保が正しくないので正しく動作する訳がないのですが、あたかもコンパイル時に文法エラーが出るかのように説明されているので回答者が当惑したと言う状況ですね。正確な説明であれば、もっとみなさん的確に答えられたと思います。
No.4 で、実行時エラーであることが明確に説明されています。
doss さんが書きました:
softyaさんの言うように普通の配列に書き直したらしっかりと動作しました。
具体的にどのように書き直したのですか?
softyaさんは STLのvector を薦めていて、「普通の配列」ではありませんよね。
次のようにしたということですか?
コード:
this->charctor = new CHARCTOR[10];
みけCAT さんが書きました:
ここで1要素しか確保していないのに、2要素目(1-origin)以降にアクセスしたら、その時の動作は保証されないと思います。
2番目、3番目(0-origin)にアクセスしてもエラーが出ないというのは不思議ですね。
これは興味深い問題です。
ヒープのメモリ管理の問題なので実装依存ですが、ちょっと調べてみました。
VC++ 2008 Express Edition では、メモリウィンドウが使えたのに、
VC++ 2010 Express Edition では、使えなくなったので、
次のようなプログラムを書いてみました。
コード:
#include <iostream> // cout, endl
#include <cstring> // strcpy
#include <iomanip> // setw
using namespace std;
class CHARCTOR {
public:
char buf[32];
CHARCTOR() { strcpy(buf, "abcdefghijklmnopqrstuvwxyz01234"); }
};
void dump(void *vp, size_t n)
{
int *p = static_cast<int *>(vp);
n /= sizeof(int);
cout << hex << setfill('0');
for (size_t i = 0; i < n; i++)
cout << p + i << ": " << setw(8) << p[i] << endl;
}
int main()
{
CHARCTOR *cp1 = new CHARCTOR;
CHARCTOR *cp2 = new CHARCTOR;
cout << "cp1 = " << cp1 << endl;
cout << "cp2 = " << cp2 << endl;
dump(cp1 - 1, sizeof(CHARCTOR) * 5);
}
実行結果を編集したもの
コード:
cp1 = 005F1290
cp2 = 005F12B8
005F1270: 005f1450
005F1274: 00000001
005F1278: 04d8a9a1
005F127C: 0800b210
005F1280: 00000000
005F1284: 005f1260
005F1288: 03d8a9a6 # cp1 の管理情報
005F128C: 0800b216 # cp1 の管理情報
005F1290: 64636261 # cp1
005F1294: 68676665
005F1298: 6c6b6a69
005F129C: 706f6e6d
005F12A0: 74737271
005F12A4: 78777675
005F12A8: 31307a79
005F12AC: 00343332
005F12B0: 03d8a9a6 # cp2 の管理情報
005F12B4: 0800b211 # cp2 の管理情報
005F12B8: 64636261 # cp2
005F12BC: 68676665
005F12C0: 6c6b6a69
005F12C4: 706f6e6d
005F12C8: 74737271
005F12CC: 78777675
005F12D0: 31307a79
005F12D4: 00343332
005F12D8: 05d8a9a0 # 未割当領域の管理情報
005F12DC: 0800b211
005F12E0: 0006a260
005F12E4: 00000001
005F12E8: 00000000
005F12EC: 00000000
005F12F0: 1bd9a9bf
005F12F4: 0000b217
005F12F8: 005f1748
005F12FC: 005f1418
005F1300: 00000000
005F1304: 00000000
005F1308: 00000000
005F130C: 00000000
new で確保された領域の直前の 8バイトはメモリの管理情報が入っています。
new で確保された領域の後は、未割当領域の管理情報が入っているようです。
this->charctor[1] = CHARCTOR::CHARCTOR(); ではこの管理情報を破壊してしまうので
No.4 の dossさんの説明の「実行が終わった際に、... ヒープが壊れていることが
原因として考えられます。」となるのだと思います。
this->charctor[2] = CHARCTOR::CHARCTOR();
this->charctor[3] = CHARCTOR::CHARCTOR();
これらは、単に未割当領域を無断で使っているだけで問題が発覚しないようです。