4

次の C コードでは、セグメンテーション違反が発生します。

#include <stdio.h>
#include <stdint.h>

int main(){
        uint32_t *a;
        uint32_t idx=1233245613;
        a[idx]=1233;
        return 0;
}

Cでuint32_tを配列のインデックスとして使用するにはどうすればよいですか? または、uint32_t と 12 桁の数字をインデックスとして取得できる配列のような構造を使用するにはどうすればよいですか?

あらゆる種類の助けをいただければ幸いです。

4

6 に答える 6

9
  • 変数「a」は単なるポインタ変数です。
  • ポインタ変数は、メモリ位置のアドレスを保持します。
  • 必要なスペースがすでに割り当てられているメモリ位置を指す必要があります。

また、配列内のかなり遠くまでインデックスを作成しようとしています。これに使用できる十分なメモリがない可能性があるため、必ず NULL を確認してください。

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

int main(void){

        uint32_t *a;
        uint32_t idx=1233245613;

        //This allows you to index from 0 to 1233245613
        // don't try to index past that number
        a = malloc((idx+1) * sizeof *a);
        if(a == NULL)
        {
           printf("not enough memory");
           return 1;
        }


        a[idx]=1233;
        free(a);
        return 0;
}
于 2009-03-16T13:00:36.093 に答える
4

「12 桁の数字」をインデックスとして使用する場合、10 億以上のアイテムが必要であることを意味します。各項目が uint32_t であるため、それぞれが 4 バイトのメモリを必要とすることを意味します。したがって、このアレイの合計メモリは約 4 GB になります。パフォーマンスやその他の理由から、通常、配列はそれほど大きくしません。

これらの数十億のアイテムのそれぞれが本当に必要な場合は、この種の巨大な配列の実装に適した、おそらくRed-Black Treesなどのディスクを利用したアルゴリズムを調べてください。

于 2009-03-16T13:06:28.480 に答える
2

まず、スペースを a に割り当てる必要があります。

そのコードが実行されると、a はおそらく所有していないメモリ内のスペースを指します。
それにアクセスしようとすると (実際には + 1233245613 にアクセスしようとすると)、明らかに所有していないメモリ内のスペースにアクセスすることになります。

#include <stdio.h>
#include <stdint.h>

int main(){
        uint32_t *a;
        uint32_t idx=1233245613;
        a = malloc(sizeof(unit32_t) * (idx+1));//+1 cause remember, arrays are 0-based
        if(a == NULL) 
        {
           printf("Array could not be allocated"); 
           return 1;
        }
        a[idx]=1233;
        free(a);//good practice to avoid memory leaks
        return 0;
}

しかし、それでもGIANT配列を使用しているという問題は解決しません。標準的なセットアップ (デスクトップまたはほとんどのサーバーでさえ) は、4.6GB のメモリを割り当てようとすると、停止します。したがって、それを考慮していない限り、おそらく一歩下がって、何をしようとしているのか、どのようにしようとしているのかを再考する必要があるでしょう.

于 2009-03-16T13:01:26.153 に答える
1

うわあ。それはめちゃくちゃです。

わかった。ここで 2 つの問題があります。最初の問題は、整数へのポインターを宣言し、それを何も指さなかったのに、それを使用しようとしたことです。これは単なるバグです。ほとんどの場合、ポインターは、プロセスの有効なメモリでさえない場所 (または NULL) を指している可能性があります。その場合、それを使用しようとすると、得たのと同じようにセグメンテーション違反が発生します。

2 番目の問題は、インデックスを作成しようとしている値です。ポインターにメモリを割り当てたとしても、4.8 ギガバイトを割り当てることができたのではないかと、私は真剣に疑っています。ほとんどのコンピューターは、それほど多くの RAM を搭載していません。また、1 つの連続したチャンクにそれほど多くの RAM を搭載していないことも確かです。配列に割り当てたメモリを超えてインデックスを作成しようとすると、ほぼすべてが発生する可能性がありますが、それをはるかに超えると、セグメンテーション違反が発生する可能性が高くなります。

于 2009-03-16T13:41:58.460 に答える
1

次の 2 つが必要です。

  • auint32_t a[2000000000] のような配列にメモリを割り当てます。
  • 4Gb 以上のメモリに対応できる 64 ビット アーキテクチャでコンパイルします。
于 2009-03-16T13:16:09.160 に答える
0

a は、決定的なものを指さないポインターです。あなたは配列が欲しい

uint32_t a[42];

42 個の整数の配列を作成します。ただし、この配列またはその他の適切な配列の範囲外にあるため、アクセスすると問題が発生します (正確には未定義の動作)。

于 2009-03-16T13:02:58.210 に答える