自分のコードの多くが c99 規則に違反していて、未定義の動作につながっていることに気がついた最後の数日/数週間の不安から、私は ISO/IEC 9899:TC3 ドラフト ペーパーを明示的に読み始めました。特に、付録「J.2 未定義の動作」は、これらの規則に違反するコードをコンパイルするのが難しい理由のほとんどが論理的であり、場合によっては、少なくとも「まあ、わかりません。それの何が問題なんだ、でも私はそのように「しなければならない」」しかし、1つのポイントがあります...
「要求されたサイズがゼロの calloc、malloc、または realloc 関数の呼び出しによって返された null 以外のポインターが、オブジェクトへのアクセスに使用されます (7.20.3)。」
(ISO/IEC 9899:TC3 の「J.2 未定義の動作」を読んでいないすべての人のために、このセクションでは未定義の動作が発生するケースについて説明します)。
そのため、その事件について頭の中で非常に多くの質問があります。
初めに:
サイズがゼロのメモリ ブロックを割り当てる必要があるのはなぜですか?
そして、そのようなブロックを手に入れたら、それで何ができますか?
未定義の動作を回避する目的で、おそらく、それが指しているメモリにアクセスしたくない...
だから私はもう少し調査をしました....いくつかの異なるmalloc()マニュアルページを探しました。そして Linux malloc(3) man で見つけました:
「サイズが 0 の場合、malloc() は NULL を返すか、後で free() に正常に渡すことができる一意のポインター値を返します。」
これが私を助けた唯一のことは、あなたと私自身に追加の質問があったことです。同じ条件で同じパラメーターを使用した関数呼び出しが異なる結果を返す可能性がある場合は、想像するのはそれほど難しいことではありません。要求されたサイズがゼロのブロックへの null 以外のポインターは、望ましくない副作用である可能性があります。これはどういう意味ですか
if ((void *ptr = malloc (0)) == NULL)
{
/*...*/
}
これじゃ足りない?このような *alloc 呼び出しを処理する必要がありますか?
if (X <= 0)
{
if ((*ptr = malloc (X)) != NULL)
{
exit (*);
}
else
{
/*...*/
}
}
else
{
if ((*ptr = malloc (X)) == NULL)
{
/*...*/
}
}
しかし、たとえそれが予想されたとしても、そのような
「後で free() に正常に渡すことができる一意のポインター値」
、それを扱う方法は?私はそれを変更することができました...私はそれを解放することさえ許されています(ところで、他のすべての割り当てられたメモリでも行う必要があるように、解放する必要があるということですか、それともあなたが許可されているだけですか?コードフローを壊さないでください
このようなポインターを作成するだけの違いは何ですか?
void *X = (void *)"1234abc";
誰かがその科学の哲学について私を助けてくれることを願っています.