0

私はプロジェクトに取り組んでおり、コード内のバグを見つけるために最後の 1 時間を費やしました。よく調べてみると、ずっと問題だった奇妙なことに気づきました。

私の配列の最初の要素のアドレスは奇妙に と等しいmemcmp()です。コードを分離してテスト コードを試したところ、同様の結果が得られました。誰かがこの奇妙な振る舞いを説明できますか?

#include <stdio.h>
#include <string.h>

int main(void)
{
    char buf[256];

    char *p1 = buf;
    char *p2 = buf + 3;

    if (memcmp(p1, p2, sizeof(char *)) == 0) {
        puts("equal...");
    }

    p1 = buf + 100;
    p2 = p1  + 3; 

    if (memcmp(p1, p2, sizeof(char *)) == 0) {
        puts("equal...");
    }
    return 0;
}
4

5 に答える 5

2

未定義の動作があります。

単純な整数または配列に関係なく、ローカル変数は初期化されません。それらの値は不定です。初期化が未定義の動作につながる前に、何らかの方法でそれらを使用し、それらから読み取ることもできます。

また、2 つの文字を比較するのではなく、32 ビット システムか 64 ビット システムかによって、一度に 4 文字または 8 文字を比較しています。単一の文字を比較したい場合は、使用する必要がありますsizeof(char)(これは常に と等しいと指定されています1)。ポインターを比較するのではなく、ポインターが指すものを比較しています。

2 つの単一文字を比較したい場合は、==代わりに、 eg*p1 == *p2または plainlyのように、compare-equal 演算子を使用しbuf[0] == buf[3]ます。

于 2016-07-23T07:25:35.710 に答える
1

memcmpアドレスを比較しません。メモリを比較します。

int memcmp(const void *s1, const void *s2, size_t n);

memcmpnと の最初のバイトをs1比較してs2、それらが等しいかどうかを確認します。

ここで、あなたは持っています

if (memcmp(p1, p2, sizeof(char *)) == 0) {

sizeof(char *)アーキテクチャに応じて、おそらく 4 または 8 のポインター サイズになります。

sizeof(char *)これは、p1 と p2の最初のバイトが等しいかどうかを比較していることを意味します。このデータを初期化しないため、何が起こるかはかなりランダムになります。あなたの実際のコードがそれをゼロにしていると仮定しています。これは、なぜそれが常に等しいかを簡単に説明します。

于 2016-07-23T07:26:09.523 に答える
0

デバッガーでコードを実行し、buf の内容を確認します。一部のコンパイラは、デバッグ モードで配列内のすべての項目をゼロにし、リリース ビルドでそれらに不定値を与えます。または、リリース ビルドでコードを実行し、それらがまだ等しいかどうかを確認します

于 2016-07-23T07:26:27.283 に答える
0

渡すポインターではなくmemcmp()、メモリに存在するコンテンツを比較すると思います。ポインター (アドレス) を比較する場合は、ポインターをポインターに渡し、サイズを sizeof(1) として渡します。

したがって、質問のコードを修正しました

/* to compare addresses */
/* simple one */
if(p1 == p2)

/* redundant one */
if(!memcmp(&p1, &p2, sizeof(p1))
于 2016-07-23T07:27:17.827 に答える