0

私のアプリケーションでは、データを解析するために、同様にネストされたリンクリストに従うネストされたループのペアがあります。私は愚かな大失敗を犯し、1 つの構造体を子構造体 EG としてキャストしました。

if (((ENTITY *) OuterEntityLoop->data)->visible == true) {

それ以外の:

if (((ENTITY_RECORD *) OuterEntityLoop->data)->entity->visible == true) {

これにより、実行の約 70% でアプリケーションが完全に停止するという問題が発生しました。プログラム フローの診断printfは、奇妙な順序で実行されるか、まったく実行されず、ほとんどの場合、数回自然に回復しましたが、アプリが壊れました。

これが問題です。内部のロジックを完全に切り詰めた後でも、ロジックのバグに基づく無限ループではなく、ループに myのみが含まれるまで、printfまだ壊れていました。

問題 2: 構造体が正しく識別されなかった場合、存在しないプロパティにアクセスしようとすると、既存のプロパティがなくてもエラーが発生しました。

私の質問は次のとおりです。

  1. なぜこのメモリが壊れたのですか?ガベージ メモリを読み取るだけで、プログラムの制御構造が破壊される可能性がありますか? そうでない場合、Electric Fence が文句を言わなくなったとしても、まだどこかに漏れがあるということですか?
  2. 存在しないプロパティについて不平を言った理由は、実際にあるものではなく、指定された型定義に従っているためだと思います。入力したので、これはあまり疑問の余地がありませんが、ここでベースから外れていないことを確認したいと思います.
4

2 に答える 2

1

プログラムが無効なメモリにアクセスしたときに何が起こるかは、たとえ読み取りであってもわかりません。一部のシステムでは、メモリ読み取り操作は有効であるか、即時のプログラム クラッシュを引き起こしますが、他のシステムでは、誤った読み取りが何かを行うためのシグナルとして誤って解釈される可能性があります。PC を使用しているか組み込みシステムを使用しているかを指定しませんでしたが、組み込みシステムでは、多くの場合、読み取り時にさまざまなアクションをトリガーするように設計された多くのアドレスがあります [たとえば、シリアル ポートから受信したデータをデキューしたり、割り込みを確認したりします] ]; このようなアドレスを誤って読み取ると、シリアル データが失われたり、実際には処理されていない割り込みが処理されたと割り込みコントローラーが認識したりする可能性があります。

さらに、一部の組み込みシステムでは、無効なアドレスを読み取ろうとすると、実際には設計によるものではなく、偶然により、さらに悪い影響が生じる場合があります。たとえば、私が設計したあるシステムでは、読み取りサイクルに続いてバスから降りるのが少し遅いメモリ デバイスを接続する必要がありました。次のメモリ読み出しが、少なくとも 1 つのウェイト ステートを持つメモリ領域、または別のバス上にあるメモリ領域から実行された場合、問題はありません。ただし、高速外部メモリ パーティションで実行されているコードがその領域を読み取ろうとすると、メモリ デバイスがバスからすぐに降りられないため、次にフェッチされる命令の一部のビットが破損します。これらすべての最終的な効果は、いくつかの場所にあるコードから低速デバイスにアクセスすることは問題ありませんでした。

于 2013-11-15T19:39:56.500 に答える
1

C へようこそ。C では、キャストの力を利用して、メモリの任意の部分を任意のオブジェクトのように見せることができますが、自己責任で行ってください。キャストしたものが実際にはその型のオブジェクトではなく、その型に別のものへのポインターが含まれている場合、クラッシュする危険があります。プロセスの仮想メモリ アドレス空間に実際にマップされていないランダム メモリを読み取ろうとしても、コアが発生する可能性があるため、NULL ポインターのように、読み取り許可を持たないメモリの特定の領域からの読み取りもコアを引き起こす可能性があります。

例:

#include <stdio.h>
#include <stdlib.h>

struct foo
{
    int x;
    int y;
    int z;
};

struct bar
{
    int x;
    int y;
    struct foo *p;
};

void evil_cast(void *p)
{
    /* hmm... maybe this is a bar pointer */
    struct bar *q = (struct bar *)p;
    if (q != NULL) /* q is some valid pointer */
    {
        /* as long as q points readable memory q->x will return some value, */
        /* this has a fairly high probability of success */
        printf("random pointer to a bar, x value x(%d)\n", q->x);
        /* hmm... lets use the foo pointer from my random bar */
        if (q->p != NULL)
        {
            /* very high probabilty of coring, since the likely hood that a */
            /* random piece of memory contains a valid address is much lower */
            printf("random value of x from a random foo pointer, from a random bar pointer x value x(%d)\n", q->p->x);
        }

     }
}

int main(int argc, char *argv[])
{
    int *random_heap_data = (int *)malloc(1024); /* just random head memory */
    /* setup the first 5 locations to be some integers */
    random_heap_data[0] = 1;
    random_heap_data[1] = 2;
    random_heap_data[2] = 3;
    random_heap_data[3] = 4;
    random_heap_data[4] = 5;
    evil_cast(random_heap_data);
    return 0;
}
于 2013-11-14T06:56:11.717 に答える