4

スラックウェアはこちら。私はちょうどメモリのものとポインタをいじっていました...私はそれらについてもう少し学びたかったので、C ++で配列を作成し、その中の最初の項目のメモリアドレスを調べました...:

string foo[3] = {"a", "b", "c"};
cout << *(&foo[0]-4) << endl;

これを出力しました: http://pastebin.com/K0HAL5nJ コード全体:

#include <iostream>

using namespace std;

int main()
{
    string foo[3] = {"a", "b", "c"};
    cout << &foo[0] << " minus " << &foo[1] << " equals " << int(&foo[0])-int(&foo[1]) << endl;
    cout << *(&foo[0]-4) << endl;
    cout << "Hello world!" << endl;
    return 0;
}

私は C++ の完全な初心者であり、なぜこれが発生するのかまったく理解できません... この種のコードは想定されていないことはわかっています... しかし、それでも、そこで何が起こったのか説明してもらえますか?

4

4 に答える 4

6

未定義の動作です。&foo[0]最初のオブジェクトのアドレスが得られstd::string、そこから 4 を引きます。§5.7 加法演算子から:

ポインターオペランドと結果の両方が同じ配列オブジェクトの要素を指している場合、または配列オブジェクトの最後の要素の 1 つ後ろを指している場合、評価はオーバーフローを生成しません。それ以外の場合、動作は未定義です。

未定義の動作とは、何でも経験できることを意味します。おそらく起こっているのは、有効なstd::stringオブジェクトではない、配列の先頭の 4 位置前のメモリ領域が として扱われていることstd::stringです。これは、醜いことが起こることにつながります。

于 2013-03-22T00:42:58.507 に答える
2

ポインタの追加と要素のサイズ


ポインターに整数を追加すると、整数は、ポインターが指すタイプの要素サイズで乗算されます。

// Assume sizeof(int) is 4.
int b[100];  // b is an array of 100 ints.
int* p;      // p is a a pointer to an int.
p = b;       // Assigns address of first element of b. Ie, &b[0]
p = p + 1;   // Adds 4 to p (4 == 1 * sizeof(int)). Ie, &b[1]

http://www.fredosaurus.com/notes-cpp/arrayptr/26arraysaspointers.html

于 2013-03-22T01:26:08.567 に答える
1
  cout << *(&foo[0]-4) << endl;

このコードは foo[-4] を出力することです

このコードを試してください。

 cout << *(&foo[4]-4) << endl;

これは foo[0] を出力します

 T * p;
 int n;

p+npadd sizeof(T *)*nのアドレス

ポインタの加算と要素のサイズ
ポインタに整数を加算すると、ポインタが指す型の要素のサイズが整数に乗算されます。

// Assume sizeof(int) is 4.
int b[100];  // b is an array of 100 ints.
int* p;      // p is a a pointer to an int.
p = b;       // Assigns address of first element of b. Ie, &b[0]
p = p + 1;   // Adds 4 to p (4 == 1 * sizeof(int)). Ie, &b[1]
于 2013-03-22T00:52:31.960 に答える
1

割り当てた配列のアドレス空間外のメモリにアクセスしているため、未定義の動作が発生します。

 string foo[3] = {"a", "b", "c"};
 cout << &foo[0] << " minus " << &foo[1] << " equals " 
      << int(&foo[0])-int(&foo[1]);

 &foo[0] get the memory address of "a",
 &foo[1] get the memory address of "b";
 the output is OK since both address are in range of foo's address space

cout << *(&foo[0]-4) << endl;
 You tried to get the value at address of ("a" -4),
since this address is outside the address of foo, it is undefined behavior. 
于 2013-03-22T00:53:07.410 に答える