0

malloc を呼び出す関数内の場所を変更すると、セグメンテーション違反が発生します。このコードは正常に機能し、「End\n」を出力します。

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

int main() {    

    int **pptr;
    if (!( *pptr = malloc(4) ))
        return 1;

    int *ptr;
    if (!( ptr = malloc(4) ))
        return 1;

    ptr[0]= 1;
    printf("Point 1\n");

    free(ptr);

    (*pptr)[0] = 1;

    free(*pptr);
    printf("End\n");
    return 0;
}

ただし、この一見同等のコードは、セグメンテーション違反から「ポイント 1\n」の前で終了します。

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

int main() {    

    int *ptr;
    if (!( ptr = malloc(4) ))
        return 1;

    ptr[0]= 1;
    printf("Point 1\n");

    free(ptr);

    int **pptr;
    if (!( *pptr = malloc(4) ))
        return 1;
    (*pptr)[0] = 1;

    free(*pptr);
    printf("End\n");
    return 0;
}

私は何が欠けていますか?(ちょっと初心者です)

その他の情報: gcc を使用して、Ubuntu で Netbeans を使用しています。

4

2 に答える 2

5

両方のプログラムで、ここで未定義の動作を呼び出しています。

int **pptr;
if (!( *pptr = malloc(4) ))
    return 1;

pptrによって返されたポインタを格納するために逆参照されている初期化されていないポインタですmalloc。未定義の動作のため、最初のものはたまたま機能しているように見えますが、pptrたまたま指している場所でメモリが破損しています。

pptr2 つ目は、たまたま書き込みできないメモリ領域を指しているため、失敗します。

さらに、上記のコードでは anint*が割り当てられているため、malloc(4)安全ではありません。を使用しmalloc(sizeof(int*))ます。たとえば、64 ビット システムには通常、8 バイトのポインターがあります。

于 2013-10-05T17:48:04.680 に答える
2

What is sizeof(int)? If it's > 4 then yes, you are invoking undefined behavior.

When invoking undefined behavior, yes, order can matter. Anything can matter. Whether your system time is even or odd at start of run of program can (but probably won't) matter. That's what undefined means.

In this case, I suspect the two mallocs somehow informed your compiler on what memory to allocate, and you "got lucky" in the first case in that it happened to be overwriting to writeable space. Of course in the larger scheme you got unlucky, since I suspect you failed silently.

Anyway, start by making the program correct, then figure out what your UB is, then figure out what implementation details may have caused it.

于 2013-10-05T17:43:43.583 に答える