ローカル変数のメモリにそのスコープ外でアクセスできますか?

1060

私は次のコードを持っています。

#include <iostream>

int * foo()
{
    int a = 5;
    return &a;
}

int main()
{
    int* p = foo();
    std::cout << *p;
    *p = 8;
    std::cout << *p;
}

そして、コードは実行時の例外なしで実行されています!

出力は 58

どうしてですか?ローカル変数のメモリは、その関数の外部からアクセスできませんか?

20 answers

4836
Eric Lippert 2011-06-23 10:01.

どうしてですか?ローカル変数のメモリは、その関数の外部からアクセスできませんか?

あなたはホテルの部屋を借ります。ベッドサイドテーブルの一番上の引き出しに本を置いて寝ます。あなたは翌朝チェックアウトしますが、あなたの鍵を返すことを「忘れて」ください。あなたは鍵を盗みます!

1週間後、ホテルに戻り、チェックインせず、盗まれた鍵を持って古い部屋に忍び込み、引き出しを調べます。あなたの本はまだそこにあります。驚くべき!

どうしてそれができるのでしょうか?部屋を借りていない場合、ホテルの部屋の引き出しの中身にアクセスできませんか?

まあ、明らかにそのシナリオは現実の世界で問題なく発生する可能性があります。部屋にいることを許可されなくなったときに本が消えるような不思議な力はありません。また、鍵を盗まれて部屋に入るのを妨げる不思議な力もありません。

ホテルの管理者はあなたの本を削除する必要はありません。あなたは彼らと契約を結んでおらず、あなたが物を置き去りにすると、彼らはあなたのためにそれを細断するだろうと言っていました。盗まれた鍵を持って不法に部屋に戻って戻ってきた場合、ホテルのセキュリティスタッフはあなたが忍び込んだのを捕まえる必要はありません。あなたは彼らと契約を結んでいませんでした。部屋の後で、あなたは私を止める必要があります。」むしろ、あなたは彼らと「後で私の部屋に忍び込まないことを約束する」という契約に署名しました。それはあなたが破った契約です

この状況では、何でも起こり得ます。本はそこにあることができます-あなたは幸運になりました。他の誰かの本がそこにあり、あなたの本がホテルのかまどにある可能性があります。あなたが入ったときに誰かがあなたの本をバラバラに引き裂いてそこにいる可能性があります。ホテルはテーブルと本を完全に取り外して、ワードローブと交換することができたはずです。ホテル全体が取り壊されてサッカースタジアムに置き換わる可能性があり、忍び寄っている間に爆発で死ぬことになります。

何が起こるかわかりません。ホテルをチェックアウトし、後で違法に使用するための鍵を盗んだとき、システムの規則に違反すること選択したため、予測可能で安全な世界に住む権利を放棄しました。

C ++は安全な言語ではありません。それはあなたが元気にシステムのルールを破ることを可能にします。許可されていない部屋に戻って、もうそこにいないかもしれない机をくまなく探し回るなど、違法で愚かなことをしようとしても、C ++はあなたを止めません。C ++よりも安全な言語は、パワーを制限することでこの問題を解決します。たとえば、キーをより厳密に制御します。

更新

神聖な良さ、この答えは多くの注目を集めています。(理由はわかりません-私はそれを単なる「楽しい」小さなアナロジーだと考えましたが、何でもです。)

これをもう少し技術的な考えで更新するのは密接な関係があるのではないかと思いました。

コンパイラーは、そのプログラムによって操作されるデータのストレージを管理するコードを生成するビジネスを行っています。メモリを管理するためのコードを生成する方法はたくさんありますが、時間の経過とともに2つの基本的な手法が定着してきました。

1つ目は、ストレージ内の各バイトの「ライフタイム」、つまり、プログラム変数に有効に関連付けられている期間を事前に簡単に予測できない、ある種の「長寿命」ストレージ領域を用意することです。時間の。コンパイラーは、必要なときにストレージを動的に割り当て、不要になったときにストレージを再利用する方法を知っている「ヒープマネージャー」への呼び出しを生成します。

2番目の方法は、各バイトの存続期間がよく知られている「短命」のストレージ領域を用意することです。ここでは、ライフタイムは「ネスト」パターンに従います。これらの短命の変数の中で最も長命の変数は、他の短命の変数の前に割り当てられ、最後に解放されます。寿命の短い変数は、寿命の長い変数の後に割り当てられ、それらの前に解放されます。これらの短命の変数の存続期間は、長命の変数の存続期間内に「ネスト」されます。

ローカル変数は後者のパターンに従います。メソッドが入力されると、そのローカル変数が有効になります。そのメソッドが別のメソッドを呼び出すと、新しいメソッドのローカル変数が有効になります。最初のメソッドのローカル変数が死ぬ前に、それらは死んでしまいます。ローカル変数に関連付けられたストレージの有効期間の開始と終了の相対的な順序は、事前に把握できます。

このため、ローカル変数は通常、「スタック」データ構造上のストレージとして生成されます。スタックには、最初にプッシュされたものが最後にポップされたものになるというプロパティがあるためです。

まるでホテルが順番に部屋を借りるだけで、部屋番号がチェックアウトするまでチェックアウトできないようなものです。

それでは、スタックについて考えてみましょう。多くのオペレーティングシステムでは、スレッドごとに1つのスタックを取得し、スタックは特定の固定サイズに割り当てられます。メソッドを呼び出すと、ものがスタックにプッシュされます。次に、元のポスターがここで行っているように、スタックへのポインタをメソッドから戻すと、それは完全に有効な100万バイトのメモリブロックの中央へのポインタにすぎません。私たちの例えでは、あなたはホテルをチェックアウトします。あなたがそうするとき、あなたはちょうど最も大きい数の占有された部屋からチェックアウトしました。あなたの後に誰もチェックインせず、あなたが不法にあなたの部屋に戻った場合、あなたのすべてのものはこの特定のホテルにまだそこにあることが保証されています

一時的な店舗には、本当に安くて簡単なスタックを使用しています。ローカルのストレージにスタックを使用するために、C ++の実装は必要ありません。ヒープを使用できます。プログラムが遅くなるので、そうではありません。

C ++の実装では、スタックに残したゴミをそのままにしておく必要はありません。これにより、後で違法に戻ってくることができます。コンパイラが、空いたばかりの「部屋」内のすべてをゼロに戻すコードを生成することは完全に合法です。繰り返しになりますが、それは高くつくからではありません。

スタックが論理的に縮小したときに、以前は有効だったアドレスが引き続きメモリにマップされるようにするために、C ++の実装は必要ありません。実装は、オペレーティングシステムに「スタックのこのページの使用は終了しました。特に断りのない限り、以前に有効だったスタックページに誰かが触れた場合にプロセスを破棄する例外を発行します」と伝えることができます。繰り返しになりますが、実装は遅くて不必要であるため、実際にはそれを行いません。

代わりに、実装により、間違いを犯してそれを回避することができます。ほとんどの時間。ある日まで、本当にひどいことがうまくいかず、プロセスが爆発します。

これには問題があります。ルールはたくさんあり、誤って破るのはとても簡単です。私は確かに何度もあります。さらに悪いことに、この問題は、メモリが破損したことが発生してから数十億ナノ秒後にメモリが破損していることが検出された場合にのみ表面化することがよくあります。

より多くのメモリセーフ言語は、あなたの力を制限することによってこの問題を解決します。「通常の」C#では、ローカルのアドレスを取得して返す方法や、後で使用するために保存する方法はありません。ローカルのアドレスを取得することはできますが、言語は巧妙に設計されているため、ローカルの存続期間が終了した後は使用できません。ローカルのアドレスを取得して返すには、コンパイラを特別な「安全でない」モードにし、プログラムに「安全でない」という単語入れて、おそらく実行しているという事実に注意を喚起する必要があります。ルールを破る可能性のある危険な何か。

さらに読むために:

  • C#が参照を返すことを許可した場合はどうなりますか?偶然にも、それは今日のブログ投稿の主題です:

    https://ericlippert.com/2011/06/23/ref-returns-and-ref-locals/

  • なぜスタックを使用してメモリを管理するのですか?C#の値の種類は常にスタックに保存されていますか?仮想メモリはどのように機能しますか?そして、C#メモリマネージャーがどのように機能するかについてのより多くのトピック。これらの記事の多くは、C ++プログラマーにも密接に関係しています。

    https://ericlippert.com/tag/memory-management/

278
Rena 2011-06-23 19:43.

ここで行っているのは、以前はのアドレスであったメモリの読み取りと書き込みですa。の外にいるfooので、これはランダムなメモリ領域へのポインタにすぎません。あなたの例では、そのメモリ領域が存在し、現在それを使用しているものは他にありません。あなたはそれを使い続けることによって何も壊さず、そして他に何もまだそれを上書きしていません。したがって、5はまだそこにあります。実際のプログラムでは、そのメモリはほとんどすぐに再利用され、これを行うことで何かが壊れます(ただし、症状はずっと後になるまで表示されない場合があります!)

から戻るとfoo、そのメモリを使用していないことをOSに通知し、別のメモリに再割り当てできるようにします。運が良ければ、再割り当てされることはなく、OSがそれを再び使用していることに気付かない場合は、うそをつきます。ただし、そのアドレスで終わるものは何でも上書きしてしまう可能性があります。

コンパイラが文句を言わない理由がわからない場合は、おそらくfoo最適化によって排除されたためです。通常、この種のことについて警告します。Cは、自分が何をしているのかを知っていることを前提としています。技術的には、ここではスコープに違反しておらず(a外部への参照はありませんfoo)、エラーではなく警告のみをトリガーするメモリアクセスルールのみです。

つまり、これは通常は機能しませんが、偶然に機能する場合もあります。

152
msw 2010-05-19 16:33.

収納スペースはまだ踏みつけられていなかったからです。その振る舞いを当てにしないでください。

84
Michael 2011-06-26 04:19.

すべての答えへの少しの追加:

あなたがそのようなことをするなら:

#include<stdio.h>
#include <stdlib.h>
int * foo(){
    int a = 5;
    return &a;
}
void boo(){
    int a = 7;

}
int main(){
    int * p = foo();
    boo();
    printf("%d\n",*p);
}

出力はおそらく次のようになります:7

これは、foo()から戻った後、スタックが解放され、boo()によって再利用されるためです。実行可能ファイルを分解すると、はっきりと表示されます。

72
Charles Brunet 2011-06-23 04:15.

C ++では、あなたができる任意のアドレスにアクセスし、それはあなたが意味するものではありませんはず。アクセスしているアドレスは無効になっています。fooが戻った後、他に何もメモリをスクランブルしないために機能しますが、多くの状況でクラッシュする可能性があります。Valgrindを使用してプログラムを分析するか、最適化してコンパイルしてみてください...

67
Kerrek SB 2011-06-23 04:15.

無効なメモリにアクセスしてC ++例外をスローすることはありません。任意のメモリ位置を参照するという一般的な考え方の例を示しているだけです。私はこのように同じことをすることができます:

unsigned int q = 123456;

*(double*)(q) = 1.2;

ここでは、123456をdoubleのアドレスとして扱い、それに書き込みます。さまざまなことが起こる可能性があります。

  1. q実際には、実際にはdoubleの有効なアドレスである可能性がありますdouble p; q = &p;
  2. q 割り当てられたメモリ内のどこかを指している可能性があり、そこで8バイトを上書きします。
  3. q 割り当てられたメモリの外側を指し、オペレーティングシステムのメモリマネージャがセグメンテーション違反信号をプログラムに送信し、ランタイムがそれを終了させます。
  4. あなたは宝くじに当選します。

設定方法は、返されたアドレスがメモリの有効な領域を指している方が少し合理的です。おそらくスタックの少し下にあるためですが、それでも無効な場所であり、決定論的なファッション。

通常のプログラム実行中に、そのようなメモリアドレスのセマンティック妥当性を自動的にチェックする人は誰もいません。ただし、などのメモリデバッガvalgrindはこれを問題なく実行するため、プログラムを実行してエラーを確認する必要があります。

29
gastush 2011-06-23 04:12.

オプティマイザーを有効にしてプログラムをコンパイルしましたか?foo()機能は非常に簡単で、インライン化や結果のコードに置き換えられている場合があります。

しかし、結果として生じる振る舞いは未定義であるというマークBに同意します。

23
Chang Peng 2011-06-23 18:45.

あなたの問題はスコープとは何の関係もありません。表示されているコードでは、関数mainは関数内の名前を認識しfooないためaこの名前を外部から直接fooにアクセスすることはできませんfoo

あなたが抱えている問題は、不正なメモリを参照するときにプログラムがエラーを通知しない理由です。これは、C ++標準が不正なメモリと正当なメモリの間の明確な境界を指定していないためです。ポップアウトスタック内の何かを参照すると、エラーが発生する場合と発生しない場合があります。場合によります。この振る舞いを当てにしないでください。プログラム時に常にエラーが発生すると想定しますが、デバッグ時にエラーが発生することはないと想定します。

18
Brian R. Bondy 2010-05-19 16:33.

メモリアドレスを返しているだけです。許可されていますが、おそらくエラーです。

はい、そのメモリアドレスを逆参照しようとすると、未定義の動作が発生します。

int * ref () {

 int tmp = 100;
 return &tmp;
}

int main () {

 int * a = ref();
 //Up until this point there is defined results
 //You can even print the address returned
 // but yes probably a bug

 cout << *a << endl;//Undefined results
}
18
Kerrek SB 2011-06-25 11:57.

これは、2日前にここで説明されていない古典的な未定義の動作です。サイト内を少し検索してください。一言で言えば、あなたは幸運でしたが、何かが起こった可能性があり、あなたのコードはメモリへの無効なアクセスを行っています。

18
AHelps 2011-06-25 12:04.

Alexが指摘したように、この動作は未定義です。実際、ほとんどのコンパイラは、クラッシュを発生させる簡単な方法であるため、これを実行しないように警告します。

発生する可能性のある不気味な動作の例については、次のサンプルを試してください。

int *a()
{
   int x = 5;
   return &x;
}

void b( int *c )
{
   int y = 29;
   *c = 123;
   cout << "y=" << y << endl;
}

int main()
{
   b( a() );
   return 0;
}

これは「y = 123」を出力しますが、結果は異なる場合があります(本当に!)。あなたのポインタは、他の無関係なローカル変数を破壊しています。

18
sam 2015-08-17 20:30.

すべての警告に注意してください。エラーを解決するだけではありません。
GCCはこの警告を示しています

警告:ローカル変数「a」のアドレスが返されました

これがC ++の力です​​。あなたは記憶を気にする必要があります。では-Werrorフラグ、この警告はエラーをbecames、今、あなたはそれをデバッグする必要があります。

17
Adrian Grigore 2011-06-24 05:31.

スタックがそこに置かれてから(まだ)変更されていないため、これは機能します。a再度アクセスする前に、他のいくつかの関数(他の関数も呼び出しています)を呼び出してください。おそらくもうそれほど幸運ではないでしょう... ;-)

16
Alexander Gessler 2011-06-25 11:57.

あなたは実際に未定義の振る舞いを呼び出しました。

一時的な作品のアドレスを返しますが、関数の終わりに一時的なものが破棄されるため、それらにアクセスした結果は未定義になります。

したがってa、変更したのではなく、以前のメモリ位置を変更しましたa。この違いは、クラッシュする場合とクラッシュしない場合の違いと非常によく似ています。

14
larsmoa 2011-06-23 04:18.

一般的なコンパイラの実装では、コードを「メモリブロックの値を、以前はa占められていたアドレスで出力する」と考えることができます。また、ローカルを含む関数に新しい関数呼び出しを追加するintと、の値a(またはa以前はポイントしていたメモリアドレス)が変更される可能性が高くなります。これは、スタックが異なるデータを含む新しいフレームで上書きされるために発生します。

ただし、これは未定義の動作であり、動作するためにこれに依存しないでください。

14
littleadv 2011-06-25 11:57.

aは、スコープ(foo関数)の存続期間中に一時的に割り当てられる変数であるため、可能です。fooメモリから戻った後は空いていて、上書きすることができます。

あなたがしていることは、未定義の振る舞いとして説明されています。結果を予測することはできません。

12
Mykola 2011-06-25 05:07.

:: printfを使用し、coutを使用しない場合、コンソール出力が正しい(?)ものは劇的に変化する可能性があります。以下のコード(x86、32ビット、MSVisual Studioでテスト済み)内でデバッガーを試してみることができます。

char* foo() 
{
  char buf[10];
  ::strcpy(buf, "TEST”);
  return buf;
}

int main() 
{
  char* s = foo();    //place breakpoint & check 's' varialbe here
  ::printf("%s\n", s); 
}
5
Ghulam Moinul Quadir 2017-07-19 21:07.

関数から戻った後、メモリの場所に保持されている値ではなく、すべての識別子が破棄され、識別子がないと値を見つけることができませんが、その場所には以前の関数によって保存された値が含まれています。

だから、ここの機能は、foo()のアドレスを返すaa、そのアドレスを返した後に破壊されます。そして、その返されたアドレスを介して変更された値にアクセスできます。

実際の例を見てみましょう。

男が場所にお金を隠し、場所を教えてくれたとしましょう。しばらくすると、お金の場所を教えてくれた男が亡くなります。しかし、それでもあなたはその隠されたお金にアクセスできます。

4
Ayub 2017-03-09 05:25.

これは、メモリアドレスを使用する「ダーティ」な方法です。アドレス(ポインタ)を返すとき、それが関数のローカルスコープに属しているかどうかはわかりません。ただの住所です。'foo'関数を呼び出したので、 'a'のアドレス(メモリ位置)は、アプリケーション(プロセス)の(少なくとも今のところは安全に)アドレス可能なメモリにすでに割り当てられています。'foo'関数が返された後、 'a'のアドレスは 'dirty'と見なすことができますが、そこにあり、クリーンアップされておらず、プログラムの他の部分(少なくともこの特定の場合)の式によって妨害/変更されていません。AC / C ++コンパイラは、このような「ダーティ」アクセスを阻止しません(ただし、気になる場合は警告する可能性があります)。何らかの方法でアドレスを保護しない限り、プログラムインスタンス(プロセス)のデータセグメントにある任意のメモリ位置を安全に使用(更新)できます。

1
Nobun 2019-05-03 00:17.

あなたのコードは非常に危険です。ローカル変数(関数の終了後に破棄されたと見なされます)を作成し、破棄された後にその変数のメモリのアドレスを返します。

つまり、メモリアドレスが有効であるかどうかにかかわらず、コードはメモリアドレスの問題(セグメンテーション違反など)に対して脆弱になります。

これは、まったく信頼できないポインタにメモリアドレスを渡しているため、非常に悪いことをしていることを意味します。

代わりに、この例を検討して、テストしてください。

int * foo()
{
   int *x = new int;
   *x = 5;
   return x;
}

int main()
{
    int* p = foo();
    std::cout << *p << "\n"; //better to put a new-line in the output, IMO
    *p = 8;
    std::cout << *p;
    delete p;
    return 0;
}

あなたの例とは異なり、この例では次のようになります。

  • intのメモリをローカル関数に割り当てる
  • そのメモリアドレスは、関数の有効期限が切れても有効です(誰も削除しません)
  • メモリアドレスは信頼できます(そのメモリブロックは空きとは見なされないため、削除されるまで上書きされません)
  • 使用しない場合は、メモリアドレスを削除する必要があります。(プログラムの最後にある削除を参照してください)

Related questions

MORE COOL STUFF

「水曜日」シーズン1の中心には大きなミステリーがあります

「水曜日」シーズン1の中心には大きなミステリーがあります

Netflixの「水曜日」は、典型的な10代のドラマ以上のものであり、実際、シーズン1にはその中心に大きなミステリーがあります.

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ケイト・ミドルトンは、州の夕食会と州の訪問中にカミラ・パーカー・ボウルズからスポットライトを奪いたくなかった、と専門家は言う.

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンが、オリビア・ワイルドが彼女とハリー・スタイルズとの間の「難しい」が「非常に友好的」な分割を恒久的にすることを望んでいる理由を見つけてください.

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする&nbsp;

エリザベス女王の死後、ケイト・ミドルトンが舞台裏で「非常に困難な時期」を過ごしていたと伝えられている理由を調べてください.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

Total War:Warhammer:Kotakuレビュー

Total War:Warhammer:Kotakuレビュー

私はこのゲームを嫌う準備ができていました。先週の前に、Total War:Warhammerについての私の考えがありました:それでもここに私は、私の手にある完成品であり、私は変わった男です。

涙の道:軍事化された帝国主義勢力がスタンディングロックキャンプを占領

涙の道:軍事化された帝国主義勢力がスタンディングロックキャンプを占領

スタンディングロックスー族のメンバーと水の保護者は、ノースダコタ州のスタンディングロックにあるオセティサコウィンキャンプを去ります。(Twitter経由のCNNスクリーンショット)火と煙がスカイラインを覆い、スタンディングロックスー族のメンバーと水の保護者が、聖なるものを守りながら建てた家、オセティサコウィン(セブンカウンシルファイアーズ)キャンプから行進し、太鼓を打ち、歌い、祈りました。ダコタアクセスパイプラインとしても知られる「ブラックスネーク」からの土地。

シアーズとKマートはイヴァンカ・トランプの商品を自分たちで取り除いています

シアーズとKマートはイヴァンカ・トランプの商品を自分たちで取り除いています

写真:APシアーズとKマートは、イヴァンカ・トランプのトランプホームアイテムのコレクションも、誰も購入したくないために削除しました。シアーズとKマートの両方の親会社であるシアーズホールディングスは、土曜日のABCニュースへの声明で、彼らが気にかけていると辛抱強く説明しましたトランプラインを売り続けるにはお金を稼ぐことについてあまりにも多く。

ポテトチップスでたった10分でスペインのトルティーヤを作る

ポテトチップスでたった10分でスペインのトルティーヤを作る

伝統的なスペインのトルティーヤは通常、オリーブオイルで柔らかくなるまで調理されたポテトから始まります(30分以上かかる場合があります)が、ケトルで調理されたポテトチップスの助けを借りてわずか10分でテーブルに置くことができます。上のビデオはすべてがバラバラにならないように裏返す方法を含め、レシピ全体を説明しますが、必要なのは4〜5個の卵と3カップのケトルチップスだけです。

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、子供向けのパズルの本の序文を書き、ジョージ王子、シャーロット王女、ルイ王子と一緒にテキストを読むと述べた.

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

Yak's Produce は、数十個のつぶれたメロンを野生動物のリハビリ専門家であるレスリー グリーンと彼女のルイジアナ州の救助施設で暮らす 42 匹の動物に寄付しました。

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

8 枚目のスタジオ アルバムのリリースに向けて準備を進めているデミ ロヴァートは、「スーパー グレート ガイ」と付き合っている、と情報筋は PEOPLE に確認しています。

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

イーサン プラスの誕生日のお祝いは、TLC のウェルカム トゥ プラスビルのシーズン 4 のフィナーレで、戦争中の母親のキム プラスと妻のオリビア プラスを結びつけました。

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

ホームオフィスのセットアップ術を極めよう!AppExert の開発者は、家族全員が一緒にいる場合でも、在宅勤務の技術を習得しています。祖父や曽祖父が共同家族で暮らしていた頃の記憶がよみがえりました。

2022 年、私たちのデジタル ライフはどこで終わり、「リアル ライフ」はどこから始まるのでしょうか?

20 年前のタイムトラベラーでさえ、日常生活におけるデジタルおよびインターネットベースのサービスの重要性に驚くことでしょう。MySpace、eBay、Napster などのプラットフォームは、高速化に焦点を合わせた世界がどのようなものになるかを示してくれました。

ニューロマーケティングの秘密科学

ニューロマーケティングの秘密科学

マーケティング担当者が人間の欲望を操作するために使用する、最先端の (気味が悪いと言う人もいます) メソッドを探ります。カートをいっぱいにして 3 桁の領収書を持って店を出る前に、ほんの数点の商品を買いに行ったことはありませんか? あなたは一人じゃない。

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

私たちが住んでいる世界を確実に理解するには、データが必要です。ただし、空間参照がない場合、このデータは地理的コンテキストがないと役に立たなくなる可能性があります。

Language