Domanda

Il seguente codice C genera un errore di segmentazione:

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

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

Come posso usare uint32_t come indice di un array in C? O come posso usare una struttura simile a array che può ottenere uint32_t e numeri a 12 cifre come indice?

Gradirei qualsiasi tipo di aiuto.

È stato utile?

Soluzione

  • La variabile " a " è solo un puntatore variabile.
  • Una variabile puntatore contiene l'indirizzo di una posizione di memoria.
  • È necessario puntare a una posizione di memoria che ha lo spazio che è necessario già allocato.

Inoltre stai cercando di indicizzare abbastanza lontano nell'array. Potrebbe non essere disponibile memoria sufficiente per questo, quindi assicurati di controllare 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;
}

Altri suggerimenti

Se desideri utilizzare un numero di 12 cifre " " come indice, ciò implica che si desidera disporre di oltre 1 miliardo di articoli. Poiché ogni elemento è un uint32_t, ciò implica che ciascuno richiede quattro byte di memoria. Pertanto, si stanno visualizzando circa 4 GB di memoria totale per questo array. Gli array di solito non sono così grandi, per prestazioni e altri motivi.

Se hai davvero bisogno di ciascuno di quei miliardi di elementi, cerca algoritmi supportati dal disco, forse Rosso -Black Trees , che sono adatti per implementare questo tipo di array gigante.

Bene, per cominciare è necessario allocare spazio a.

Quando viene eseguito quel codice, un punto in memoria è uno spazio che probabilmente non possiedi.
Quando provi ad accedervi (in realtà quando provi ad accedere a un + 1233245613) stai andando in uno spazio nella memoria che sicuramente non possiedi, e questo è un no-no e causerà un arresto anomalo.

#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;
}

Ma anche questo non risolve il problema che stai usando un array GIANT. L'impostazione standard (desktop o anche la maggior parte dei server) si strozzerà nel tentativo di allocare 4,6 GB di memoria. Quindi, a meno che tu non l'abbia preso in considerazione, probabilmente dovrai fare un passo indietro e ripensare a ciò che stai cercando di fare e come.

Hai bisogno di due cose:

  • alloca memoria per l'array a , qualcosa come uint32_t a [2000000000];
  • compilare su un'architettura a 64 bit che può indirizzare più di 4 GB di memoria.

Whoa. È incasinato.

OK. Due problemi qui. Il primo problema è che hai dichiarato un puntatore a un numero intero, non lo hai mai puntato su nulla e poi hai provato a usarlo. Questo è semplicemente un bug. Molto probabilmente, il puntatore sembra puntare a un posto che non è nemmeno memoria valida per il processo (o NULL). In tal caso, qualsiasi tentativo di utilizzarlo ti darà un segfault, proprio come hai fatto.

Il secondo problema è il valore che si sta tentando di indicizzare. Anche se avevi allocato memoria per il tuo puntatore, dubito seriamente che tu possa aver allocato 4.8 Gigabyte per esso. La maggior parte dei computer non ha quasi così tanta RAM e certamente non ha così tanto in un pezzo contiguo. Se si tenta di indicizzare oltre la memoria che è stata allocata a un array, potrebbe succedere quasi nulla, ma se si va via , molto probabilmente si otterrà un segfault.

a è un puntatore che punta a nulla di determinato. Vuoi un array

uint32_t a[42];

che crea un array di 42 numeri interi. Tuttavia, l'accesso ad esso causerà comunque problemi (comportamento indefinito per essere esatti) in quanto è molto al di fuori dei limiti di questo o di qualsiasi altro array sensibile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top