mehrdimensionales char* array



  • PCMan, du brauchst realloc()

    http://www-ccs.ucsd.edu/c/stdlib.html#realloc



  • Ich hab zwecks Lerneffekt das auch mal probiert vorerst nur mit Integern und Eindimensional.
    Nur woher weiß ich jetzt obs klappt oder nicht ?!?
    Und 2te Frage wie ruf ich malloc fuer ein 2-Dimensionales Array auf?

    char *str[20]=malloc(sizeof(char)); //Wenn ich Strings der Länge 20 einlesen will
    

    so?
    Gruß HiFish

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
    	int x=1,i=0,j=1;
    	int zw=0;
    	int *ar=(int *)malloc(sizeof(int));
    	int *zwar;
    
    	while(x)
    	{
    		scanf("%d",&zw);
    
    		if(zw==1001)
    		{
    			x=0;
    			free(ar);
    		}else if(j==i)
    		{
    			j+=10;
    			zwar=realloc(ar,j*sizeof(int));
    			ar=zwar;
    			*(ar+i)=zw;
    		}else
    		{
    			*(ar+i)=zw;
    		}
    		if(zw==1101)
    		{
    			for(x=0;x<i;x++)
    			{
    				printf("z%d:%d  ptr:%p\n",x+1,*(ar+x),(ar+x));
    			}
    		}
    		i++;
    	}
    }
    


  • HiFish schrieb:

    Nur woher weiß ich jetzt obs klappt oder nicht ?!?

    Debugger starten und nachsehen, was das Programm macht 😉

    Und 2te Frage wie ruf ich malloc fuer ein 2-Dimensionales Array auf?

    char *str[20]=malloc(sizeof(char)); //Wenn ich Strings der Länge 20 einlesen will
    

    so?

    Nein, so bestimmt nicht - du deklarierst ein Array aus 20 char-Zeigern und pointerst es dann auf einen 1 Byte großen Heap-Bereich.

    char** data = malloc(anzahl*sizeof(char*));
    for(i=0;i<anzahl;++i)
      data[i]=malloc(laenge+1);//+1 für schließendes '\0'
    
    ...
    
    for(i=0;i<anzahl;++i)
      free(data[i]);
    free(data);
    


  • ok habs jetzt mal mit char versucht, funktioniert auch (beinahe..)
    Zum einen gibt er quatsch bei den ersten beiden Einträgen aus(aber nur wenn man ca. 15+ Einträge hat bei nur zB. 5 Einträgen passt alles):

    s1:�    1       ▒2      82      X2 //1 eingegeben
    s2:�                                     //2 eingegeben
    s3:3                                    //...
    s4:4
    s5:5
    s6:6
    

    und nach ca. 20 Eingaben bricht das Programm mit folgender Fehlermeldung ab:

    *** glibc detected *** ./dyn: realloc(): invalid next size: 0x09e83008 ***
    ======= Backtrace: =========
    /lib/libc.so.6[0x4d5345]
    /lib/libc.so.6(__libc_realloc+0x101)[0x4d5d30]
    ./dyn[0x8048592]
    /lib/libc.so.6(__libc_start_main+0xc6)[0x484de6]
    ./dyn[0x8048439]
    ...
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
    	int x=1,akt_pos=0,length=0,i=0;
    	char zw[21];
    	char **ar=malloc(sizeof(char*));
    	char *zwar;
    
    	while(x)
    	{
    		scanf("%s",&zw);
    
    		if(strstr(zw,"end")!=0)
    		{
    			x=0;
    			for(i=0;i<=length;i++)
    			{
    				free(ar[i]);
    			}
    			free(ar);
    
    		}else if(length==akt_pos)
    		{
    
    			realloc(ar,(10*sizeof(char*)));
    			for(i=0;i<=10;i++)
    			{
    				ar[length+i]=malloc(21);
    			}
    			length+=10;
    			strncpy(ar[akt_pos],zw,20);
    		}else
    		{
    			strncpy(ar[akt_pos],zw,20);
    		}
    		akt_pos++;
    		if(strstr(zw,"print")!=0)
    		{
    			for(x=0;x<akt_pos;x++)
    			{
    				strncpy(zw,ar[x],20);
    				printf("s%d:%s \n",x+1,zw);
    			}
    		}
    
    	}
    }
    


  • Bei realloc() mußt du die Gesamtgröße des neuen Bereiches angeben, nicht nur die Größenänderung (und außerdem ändert die Funktion nicht den übergebenen Parameter, sondern gibt die neue Adresse per return zurück):

    ar=realloc(ar,(10+length)*sizeof(char*));
    


  • jetzt geht es,hätte ich selber sehen müssen/sollen 😉
    vielen Dank für den Hinweis 🙂



  • Hallo,
    Danke für die Hilfe, aber ich sehe, dass ich mich bei den Eingaben dennoch darauf einigen muss, dass keine Eingabe quasi länger als 21 Zeichen ist.

    Mit der VCL hat man nämlich diese Probleme nicht mehr (wobei ich glaube, das ist nicht ganz korrekt, sie werden nur von C++ und seinen Bibliotheken umgangen).



  • #include <stdlib.h>
    #include <string.h>
    
    char **table=NULL;
    size_t table_size=0; /* in feldern, nicht bytes */
    
    void
    resize_table (size_t new_size)
    {
      int i;
    
      if(new_size!=table_size)
      {
        /* falls table verkleinert werden soll, dann ueberzählige strings freigeben */
        for(i=new_size; i<table_size; ++i)
          free(table[i]);
    
        if(table_size==0)
          table=(char**)malloc(sizeof(char*)*new_size);
        else
          table=(char**)realloc(table,sizeof(char*)*new_size);
    
        if((table_size=new_size)==0) table=NULL;
    
        for(i=table_size; i<new_size; ++i)
          table[i]=NULL;
      }
    }
    
    void
    set_table_entry (int i, const char *str)
    {
      resize_table(i+1);
    
      if(str)
        table[i]=strdup(str);
      else
      {
        if(table[i]) free(table[i]);
        table[i]=NULL;
      }
    }
    


  • Hallo
    hatte gerade das gleiche Problem ein 2D-Feld dynamisch zu erzeugen.
    Die Lösung dafür habe ich auf folgender Internetseite gefunden:

    http://www.cpp-tutor.de/cpp/le17/le17_01.htm

    template <typename T, int r, int c>
    class matrix
    {
    T *data; // Zeiger-Zeiger(!) auf dyn. 2D-Feld
    int col; // Spalten
    int row; // Zeilen
    public:
    // ctor, allokiert 2D-Feld dynamisch
    matrix()
    {
    row = r; // Zeilen/Spalten merken
    col = c;
    // 2D-Feld dyn. allokieren
    data = new T
    [row];
    for (int i=0; i<row; i++)
    data[i] = new T[col];

    Das ist die relevante Stelle der Seite.
    Habe selbst dazu ein einfaches Bsp. geschrieben. Ist verständlicher:

    #include<iostream>
    using namespace std;

    class Array{
    public:
    Array();
    void Ausgabe();

    private:
    int Zeile;
    int Spalte;
    int** Feld; //wichtig für dynamisches 2D-Feld
    };

    Array::Array(){
    Zeile = 4;
    Spalte = 3;

    Feld = new int*[Zeile]; //wichtig für dynamisches 2D-Feld
    for(int i=0; i<Zeile; i++) //wichtig für dynamisches 2D-Feld
    Feld[i] = new int[Spalte]; //wichtig für dynamisches 2D-Feld

    for(int i=0; i<Spalte; i++){
    for(int j=0; j<Zeile; j++) Feld[i][j] = j+i; //Fülle 2D-Feld
    };
    };

    void Array::Ausgabe(){
    for(int i=0; i<Spalte; i++){
    cout<<endl;
    for(int j=0; j<Zeile; j++) cout<<Feld[i][j];
    };
    cout<<endl;
    };

    int main(){
    Array objekt;
    objekt.Ausgabe();
    system("pause");
    };



  • Tja, Templates in C wäre doch schön 😉


Anmelden zum Antworten