Vreemde waarden voor array-initialisatie

Ik ben nieuw bij programmeren in C en ik heb iets gevonden dat ik niet begrijp:

Bij het initialiseren van een array zonder gegeven waarden, dacht ik dat alle elementen nul zouden zijn. Ik heb dit paar regels code geschreven ...

int main()                    
{     
    int obj[10][4];

    for (int a = 0; a < 10; a++)
    {
        print("%d\t%d\t%d\t%d\n", obj[a][0], obj[a][1], obj[a][2], obj[a][3]);
    }            
}

... en was behoorlijk in de war door zijn output:

0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       7661
7960    2697    2260    7960
1551630361      -2130960380     146780176       -2130960380

Ik begrijp niet waarom sommige waarden nul zijn en sommige niet. Ik was zelfs nog meer in de war dat deze cijfers veranderen als ik meer code toevoeg. Ik heb bijvoorbeeld het vorige voorbeeld gewijzigd en nog een print() toegevoegd ...

int main()                    
{     
    int obj[10][4];

    print("start\tstop\tcenter\tdist\n\n");

    for (int a = 0; a < 10; a++)
    {
        print("%d\t%d\t%d\t%d\n", obj[a][0], obj[a][1], obj[a][2], obj[a][3]);
    }            
}

... dit krijgen:

start   stop    center  dist

0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       0
0       0       0       7673
7972    2709    2272    7972
1551630361      -2130960380     146780176       -2130960380

Met behulp van een grotere array worden deze nummers niet alleen aan het einde gevonden. De eerste paar waarden zijn altijd nul, maar dan gebeurt er "iets".

Ik heb een oplossing gevonden hier bij SO , met behulp van memset() , dat werkt voor mij, maar ... wat is hier aan de hand?

Kan iemand dit uitleggen, met behulp van woorden die een C-newbie zou begrijpen?

2
Nou, je hebt niet geïnitialiseerd, dus je krijgt niet-geïnitialiseerde waarden. Meestal nullen, maar nooit gegarandeerd.
toegevoegd de auteur stefan, de bron
Een tip voor verdere ontwikkeling: als u een gedrag onverwacht krijgt met echt vreemde waarden, probeer dan een valgrind run. Dit kan u aanwijzingen geven waar de fout zit (niet-geïnitialiseerde variabelen worden redelijk goed gedetecteerd door valgrind).
toegevoegd de auteur stefan, de bron
Ja, ik weet dat dit erg in het begin is, geloof me, ik weet beginners ;-) Maar het is altijd handig om te weten waarnaar je moet zoeken. Twee stappen: voeg -g toe aan de aanroep van uw compiler (u typt waarschijnlijk nu gcc -Wall -std = c99 my_file.c -o mijn_binarie , dus dit wordt gcc -g -Wall -std = c99 my_file.c -o my_binary ). Tweede stap: in plaats van als volgt uit te voeren: ./ mijn_binatie , doe je valgrind ./my_binary . En dat is het. Als er "... niet-geïnitialiseerde waarde ..." is, staat daar ook het bestand en de regel vermeld en kunt u het probleem bekijken. Probeer het gewoon met de code van uw vraag!
toegevoegd de auteur stefan, de bron
Ah, ik begrijp het. Nou, dit maakt leren een beetje moeilijker, naar mijn mening ;-)
toegevoegd de auteur stefan, de bron
@stefan: bedankt voor deze informatie, maar op dit moment is het een beetje te veel. Ik heb valgrind opgezocht en heb een bladwijzer gemaakt voor een aantal sites die ik misschien zou begrijpen nadat ik C iets langer heb gebruikt ;-)
toegevoegd de auteur xph, de bron
@stefan: Nou, het punt is ... ik codeer niet de "gebruikelijke" manier. Ik schrijf in C voor een klein Propeller-bord, met behulp van de IDE die is gebouwd voor precies die kleine computer. Ik gebruik niet eens een normale compiler, het is een all-built-in-oplossing om op de meest handige manier wat code op het bord te krijgen, ofwel "Klik op deze knop wanneer klaar" . Als ik het blijf houden, zou ik er dieper op ingaan. Misschien kan ik de tools van mijn keuze gebruiken om deze computer te programmeren, en dan is dit erg handig!
toegevoegd de auteur xph, de bron
Ja, overeengekomen. Het gaat geen 'goed' gebruik van C leren, maar dat is niet echt het punt voor mij. Dit bord is ontworpen om te bouwen en te leren over robotica en ik ben vooral gericht op sensoren, servo's, enzovoort. Uiteraard is code nodig om zaken voor elkaar te krijgen. Tenminste een reden om "in contact te komen" met C, een taal die ik tot nu toe altijd heb vermeden. Maar de IDE is ... niet echt goed. Als ik op zoek ben naar nieuwe avonturen, zal ik proberen er vanaf te komen.
toegevoegd de auteur xph, de bron

7 antwoord

Simply put, you can not assume the array is initialized to 0 unless you explicitly made the initialization yourself. The C standard does not guarantee anything about the content of the array, just that you'll have memory allocated for it.
A great reference on initializing and arrays in C general can be found here:http://www.tutorialspoint.com/cprogramming/c_multi_dimensional_arrays.htm

4
toegevoegd
... dus ik kreeg dat fout. Bedankt voor de uitleg en de link !!
toegevoegd de auteur xph, de bron

U hebt een variabele verklaring, maar geen initialisatie.

Als u wilt dat uw array nul geïnitialiseerd is, hoeft u alleen dit te doen:

int obj[10][4] = {0};
2
toegevoegd
Dank je! Nu weet ik de fout die ik heb gemaakt - alleen als sommige waarden zijn gedefinieerd, is de rest nul. Zal dat doen!
toegevoegd de auteur xph, de bron

opslagklasse type int obj [10] [4] is auto en het is opgeslagen op stapel. auto variabelen krijgen geen geïnitialiseerde waarden, dat wil zeggen dat ze afvalwaarden hebben. Als u wilt dat de array met nullen wordt geïnitialiseerd, maakt u deze globaal, dwz declareert een array buiten de functie main() .

1
toegevoegd

De beginwaarden van alles zijn niet gedefinieerd. Uw code definieert alleen een array - het kent nooit waarde toe aan wat erin staat.

1
toegevoegd
@xph Ja, dat is precies waar je het mis hebt. Niet-geïnitialiseerd betekent afvalwaarden.
toegevoegd de auteur stefan, de bron
Ja - maar de voorbeelden die ik tegenkwam suggereren dat "geen waarde" betekent "nul, dan". Heb ik dat verkeerd begrepen en betekent "geen waarde" gewoon "wat dan ook" ...?
toegevoegd de auteur xph, de bron
@stefan: snap het! :-)
toegevoegd de auteur xph, de bron

de stapel bevat prullenbak totdat het programma specifieke waarden in variabelen plaatst die op de stapel zijn gedefinieerd. De opstartcode initialiseert de stapelinhoud niet.

Opmerking: variabelen in de globale ruimte/bestands globale ruimte worden geïnitialiseerd door de opstartcode. waar is geen specifieke initializer gespecificeerd, dan is het geheugen ingesteld op 0x00.

0
toegevoegd

In eerste instantie heeft de array enkele afvalwaarden of onvoorspelbare waarden. Het is niet te voorspellen wat deze waarden zullen zijn of waar ze zich in de array zullen bevinden.

Telkens wanneer u een array in C declareert, moet u deze initialiseren voordat u hem gebruikt. d.w.z. voer een lus uit om alle arraylocaties te initialiseren naar nul of naar een willekeurig nummer dat u wilt opslaan. Op die manier weet u zeker wat de array bevat en in verdere verwerking zal uw array geen ongedefinieerd gedrag vertonen.

0
toegevoegd

Geen expert maar een hypothese uit ervaring:

Als u een array initialiseert als een statische int myArray [1000] , wijst C nieuw geheugen toe, gevuld met 1000 nullen voor de duur van het programma. Initialiseren met int myArray [1000] stelt slechts 1000 registers apart, waarvan sommige oude waarden kunnen bevatten van een eerder gebruik van het register.

0
toegevoegd