Mittwoch, 13. Mai 2009

 

Zeigerarray - Speicherlayout

Skizzieren Sie das Speicherlayout für das folgende Programm.


 /*
* File: zeigerarray.c
*
* Zweck: Beispiel fuer Zeigerarray
*
* Autor: Harald Haberstroh
*
* Algorithmus:
* Bei diesem Beispiel wird ein Array mit konstanten Strings
* angelegt (also ein Zeigerarray), dann wird ein
* 2-dimensionales Array angelegt, das dieselben Strings
* speichern kann. Als letztes ein 2-dimensionales Array,
* welches ebenfalls mit konstanten Strings initialisiert wird.
*
* Die Speichergroessen werden ermittelt.
*
* Die Zeiger des Zeigerarrays werden veraendert.
*
* Der Inhalt wird veraendert. Beim Aendern eines konstanten
* Strings gibt es einen Segmentation Fault.
*
* Es wird noch ein Makro __LINE__ verwendet, Der Preprozessor
* (Precompiler) ersetzt dieses Makro durch die aktuelle
* Zeilennummer.
*
* History: 2002-11-03
* 2007-02-14, Umlaute...
*/

/*--------------------------- includes ------------------------------*/
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>

/*--------------------------- defines -------------------------------*/

/*--------------------------- typedefs ------------------------------*/

/*--------------------------- globals -------------------------------*/

/*-------------------------- prototypes -----------------------------*/

/*----------------------------- main --------------------------------*/
int main( int argc, char *argv[] )
{
int i;
int size = 0;
char *texte[] = {
"Eine Zeile Text",
"Eine 2. Zeile Text",
"Diese Art der Initialisierung kann auch fuer Fehlermeldungen "
"verwendet werden",
"Die letzte Zeile"
};
char aTexte[sizeof(texte)/sizeof(texte[0])][80] = { { 0 } };
/* 76 Zeichen braucht der laengste
* String */
char aTexteInit[sizeof(texte)/sizeof(texte[0])][80] = {
"Eine Zeile Text",
"Eine 2. Zeile Text",
"Diese Art der Initialisierung kann auch fuer Fehlermeldungen "
"verwendet werden",
"Die letzte Zeile"
};

for (i = 0; i < sizeof(aTexte) / sizeof(aTexte[0]); i++)
strcpy(aTexte[i], texte[i]); /* Die Strings auch in's 2-dim Array
* kopieren */

printf("sizeof(texte) = %d\n", sizeof(texte));
/* 4 Zeiger, der Speicher fuer die
* konstanten Strings ist hier
* nicht mitgerechnet -> 16 Bytes */
for (i = 0, size = 0; i < sizeof(texte) / sizeof(texte[0]); i++)
size += strlen(texte[i]) + 1; /* tatsaechlicher Mindestspeicher-
* verbrauch ist die Laenge des
* Strings plus 1 fuer '\0' */
printf("... tats. Speicherbedarf sizeof(texte) + "
"Laengen der Strings (%d) = %d\n", size, sizeof(texte)+size);

for (i = 0; i < sizeof(texte) / sizeof(texte[0]); i++)
printf("sizeof(texte[%d]) = %d, strlen(texte[%d]) = %d\n"
, i, sizeof(texte[i]), i, strlen(texte[i]));
/* Speicherbedarf und Laenge des
* Strings ausgeben */

printf("sizeof(aTexte) = %d\n", sizeof(aTexte));
/* Hier wird wirklich der gesamte
* Speicherbereich ausgegeben,
* das sind 4 * 80 Bytes */

for (i = 0; i < sizeof(aTexte)/sizeof(aTexte[0]); i++)
printf("sizeof(aTexte[%d]) = %d, strlen(aTexte[%d]) = %d\n"
, i, sizeof(aTexte[i]), i, strlen(aTexte[i]));
/* Speicherbedarf und Laenge des
* Strings ausgeben */

printf("sizeof(aTexteInit) = %d\n", sizeof(aTexteInit));
/* Hier wird wirklich der gesamte
* Speicherbereich ausgegeben,
* das sind 4 * 80 Bytes */

for (i = 0; i < sizeof(aTexteInit)/sizeof(aTexteInit[0]); i++)
printf("sizeof(aTexteInit[%d]) = %d, strlen(aTexteInit[%d]) = %d\n"
, i, sizeof(aTexteInit[i]), i, strlen(aTexteInit[i]));
/* Speicherbedarf und Laenge des
* Strings ausgeben */

strcpy(aTexte[2], "Eine 3. Zeile Text");
/* In das Array kann natuerlich
* etwas kopiert werden (solange
* der String nicht zu lange
* ist...) */
printf("aTexte[2] wurde geaendert in \"%s\"\n", aTexte[2]);

printf("Zeile %d: Aenderung eines Strings (aTexte[0][0] klein)\n"
, __LINE__ + 1);
aTexte[0][0] = tolower(aTexte[0][0]);
/* Anfangsbuchstabe klein, das
* darf sein, da dies ja ein
* Array ist */

for (i = 0; i < sizeof(texte) / sizeof(texte[0]); i++)
printf("texte[%d] = \"%s\"\n", i, texte[i]);

texte[2] = aTexte[2]; /* Zeiger "verbiegen", texte[2]
* zeigt nun auf das Array
* aTexte[2] */
printf("texte[2] -> aTexte[2] = \"%s\"\n", texte[2]);

printf("Zeile %d: Aenderung nun nicht mehr konstanten Strings (texte[2][0]"
" klein)\n"
, __LINE__ + 1);
texte[2][0] = tolower(texte[2][0]); /* Das sollte gehen... */
printf("texte[2] = \"%s\"\n", texte[2]);

printf("Zeile %d: Aenderung eines konstanten Strings (texte[0][0] klein)\n"
, __LINE__ + 1);
texte[0][0] = tolower(texte[0][0]); /* Anfangsbuchstabe klein in den
* konstanten Strings -> SegFault,
* da Konstante Strings nicht am
* Stack angelegt werden */
return 0;
}

Sourcecode von zeigerarray.c (Versionsnummer entfernen).

Labels: , ,


Kommentare:

Kommentar veröffentlichen

Abonnieren Kommentare zum Post [Atom]





<< Startseite

This page is powered by Blogger. Isn't yours?

Abonnieren Posts [Atom]