-1

私はプログラミングが初めてで、次の違いを理解しようとしています

A = (char * ) malloc(sizeof(char)*n);

A = (char * ) malloc(sizeof(char)); 

また

A = new char [n];

A = new char;

特定のデータ型のオブジェクトの数を指定しない場合、コンパイラがこのポインターに割り当てる既定のメモリは何ですか。

また、私が宣言するとき

A = new char [n];
cout << A[n+1];

セグメンテーション違反は発生しません。

配列に割り当てられたものを超えてメモリにアクセスしようとしているため、セグメンテーション違反は発生しません。

4

4 に答える 4

5

メモリは「このポインタに割り当てられる」のではなく、割り当てられてから、メモリへのポインタを取得します。

これ:

char *a = malloc(sizeof(char) * n);

と同じです

char *a = malloc(n);

常にsizeof(char)1 であるため、どちらも文字に相当するデータにスペースを割り当て、最初の文字にアクセスできる場所 (または失敗した場合) へのポインターを返します。nNULL

また、C ではキャストは必要ありません。

は 1 であるためsizeof(char)、2 番目の呼び出しは次と同等です。

char *a = malloc(1);

これは、サイズ 1 のメモリ ブロックを割り当てることを意味します。これはもちろん、そのメモリ ブロックへのポインタ(ポインタ変数に格納される値a) とは異なります。ポインターは 1 文字より大きい可能性が高いですが、ブロックのサイズには影響しません。

への引数は、malloc()スペースを割り当てる文字数を指定します。

newそれはC ++であり、質問にはCのタグが付けられているため、使用法を無視しました.

于 2013-10-02T13:08:52.123 に答える
2
A = (char * ) malloc(sizeof(char)*n);

これにより、n 文字分のスペースが割り当てられます。

A = (char * ) malloc(sizeof(char)); 

これにより、1 文字分のメモリが割り当てられます。

malloc を呼び出すたびに、ヒープにメモリが割り当てられます。

もう 1 つのコードは C++ で、A がローカル変数の場合にスタック メモリを使用する点を除いて、まったく同じです。A[n+1] にアクセスすると、segfault が発生する場合と発生しない場合があります。A[n+1] は、使用が許可されているメモリ アドレスを参照できます。Segfault は、アクセスできるメモリ領域の外に出ると発生します。そのしくみは、無効なメモリにアクセスしたと見なされる「レッド ゾーン」があることです。A[n+1] がセグメンテーション違反をトリガーするのに「十分に無効」ではない場合があります。

于 2013-10-02T13:09:58.840 に答える
2
  • 文字にスペースを割り当てますN(N は正の整数値である必要があります)。

    char *ma = (char * ) malloc(N);
    char *na = new char [N];
    
    • このメモリを解放することを忘れないでください...

      delete [] na;
      free(ma);
      
  • 1 文字にスペースを割り当てる

    char *mc = (char * ) malloc(sizeof(char)); 
    char *nc = new char;
    

さて、他の人が指摘したように、この C にタグを付けましたが、コードの半分は C++ です。Cを書いていた場合、 new/を使用できずdelete、 の結果をキャストする必要はありませんmalloc

ああ、配列の最後を読み取ったときにセグメンテーション違反が発生しない理由は、これが未定義の動作であるためです。確かに SEGV が発生する可能性がありますが、チェックする必要はないため、少なくとも一部の時間は機能しているように見えるか、まったく別の方法で失敗する可能性があります。

于 2013-10-02T13:16:12.793 に答える
1

コンパイラはデータにメモリを割り当てません。アーキテクチャに応じて 4 または 8 バイトのポインターのみ。

機能に関しては、最初の 2 つと最後の 2 つに違いはありません。私が見たほとんどの C++ ライブラリは、malloc内部的にnew.

n文字を割り当てるコードを実行してn + 1th 文字を出力すると、セグメンテーション違反が発生しない可能性が最も高いnのは、 が何らかの数 (通常は 8 または 16) の倍数ではないためです。 :

void* malloc(size_t size) {
    if (size & 0x7 != size)
        size = size & 0x7 + 1;
    return _malloc(size);
}

したがって、たとえば 5 バイトを要求したmalloc場合、実際にはそのコードで 8 バイトが割り当てられます。したがって、6 番目のバイト ( n + 1) を要求すると、ガベージが返されますが、プログラムがアクセスできる有効なメモリです。

于 2013-10-02T13:10:04.043 に答える