char pointer swappen



  • ich hab ein problem mit dem tauschen von pointern auf char arrays. bei integern usw. klappts auch gut aber bei char arrays irgenwie nicht, warum? brauch ich da etwa doppelpointer? hier mal mein bisheriger code

    void swap(char *a, char *b)
    {
         char *tmp=a;
         a=b;
         b=tmp;
    };
    

    und noch ne andere frage: wenn ich zuvor mittels malloc() dynamisch speicher reserviert habe und dann die (unterschiedlich grossen!) pointer swappe wird doch trotzdem die korrekte anzahl an bytes wieder freigegeben oder?



  • Du vertauschst hier nur die Adressen der lokalen Zeiger.
    Nach dem Funktionsaufruf ist alles gleich.



  • c-newb schrieb:

    ... brauch ich da etwa doppelpointer?

    Ja, du musst Zeiger auf Zeiger übergeben!

    c-newb schrieb:

    und noch ne andere frage: wenn ich zuvor mittels malloc() dynamisch speicher reserviert habe und dann die (unterschiedlich grossen!) pointer swappe wird doch trotzdem die korrekte anzahl an bytes wieder freigegeben oder?

    Es wird die korrekte anzahl bytes freigegeben. 🙂



  • ok danke! jetzt hätt ich aber noch eine frage unabhängig von diesem thema: wie funkioniert ein split-program (also dateien in beliebig viele teile aufteilen)? reicht es aus die dateien im binärformat lesend zu öffnen und den output alle n bytes in eine andere datei umzulenken?



  • Deine swap-Funktion sieht jetzt so aus?:

    void swap(char** a, char** b) 
    { 
         char *tmp= *a; 
         *a = *b; 
         *b = tmp; 
    }
    

    @c-newb reicht es aus die dateien im binärformat lesend zu öffnen und den output alle n bytes in eine andere datei umzulenken?

    n-Byte in Puffer lesen, n-Byte aus Puffer in neue Datei schreiben, wieder Byte in Puffer lesen usw.
    mfg



  • gerie schrieb:

    Deine swap-Funktion sieht jetzt so aus?

    so sieht sie aus, ja. allerdings klappt es bisher immer noch nicht. hier mal die funktion, die diese aufruft:

    void reverse(char *str)
    {
         int len=strlen(str);
         char *tmp=(char*) malloc(len+1);
         int i;
    
         for(i=0; i<len; ++i)
                 tmp[i]=str[len-i-1];
    
         tmp[i]=0;
         swap(&str, &tmp);     
         free(tmp);  
    };
    

    wobei ich hier vermutlich wieder einen doppelpointer übergeben muss... liege ich da richtig?

    und wo liegt eigentlich der unterschied zwischen

    void swap(char **a, char **b)
    {
         char **tmp=a;
         a=b;
         b=tmp;
    };
    

    und

    void swap(char **a, char **b)
    {
         char *tmp=*a;
         *a=*b;
         *b=tmp;
    };
    

    ?



  • Du tauscht die Zeiger auf Zeiger aus, das hat keinen Effekt, das sind lokale Variable,
    nur innerhalb der Funktion vertauscht du die, ausserhalb der Funktion ändert sich nichts.

    Die zweite Variante derefrenziert die Zeiger auf Zeiger und vertauscht die ausserhalb der
    Funktion liegenden Zeiger.

    swap(&str, &tmp) ist auch falsch, weil wenn du Zeiger durchreichst, es

    void reverse(char** str) heissen mus und dann

    swap(str, &tmp);!

    mfg



  • PS free(tmp); löscht, wenn swap() erfolgreich durchgeführt wurde, den Speicher der für str angefordert wurde,
    erst späteres free(str); löscht den in der Funktion angeforderten Speicher;



  • probier so:

    #define SWAP(a,b) {void *t=a;a=b;b=t;}
    
    int main()
    {
       char *a = "hallo";
       char *b = "doof";
    
       printf ("%p %p\n", a, b);
       SWAP (a,b);
       printf ("%p %p\n", a, b);
    }
    

    🙂



  • jo ok, vielen dank euch beiden, ich glaub ich habs jetzt 🙂

    PS: das mit dem free(str) kommt dann schon noch in main().



  • habs nochmal überarbeitet aber leider klappts immer noch nicht. hier nochmal die überarbeitete version von void reverse(), diesmal mit zeiger auf zeiger. ich hoffe es findet jemand den fehler weil ich komm einfach nicht drauf.

    void reverse(char **str)
    {
         int len=strlen(*str);
         char *tmp=(char*) malloc(len+1);
         if(NULL==tmp)
              exit(1);
         int i;
    
         for(i=0; i<len; ++i)
            tmp[i]=*(str[len-i-1]);
    
         tmp[i]=0;
         swap(str, &tmp);
         free(tmp);  
    };
    


  • willst du einfach nur einen string umdrehen?
    das ist doch viel zu kompliziert so (mit malloc und swap) 😕
    🙂



  • #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void swap(char **a, char **b) 
    { 
         char *tmp=*a; 
         *a=*b; 
         *b=tmp; 
    }
    void reverse(char **str) 
    { 
         int len=strlen(*str); 
         char *tmp=(char*) malloc(len+1); 
         if(NULL==tmp) 
              exit(1); 
         int i; 
    
         for(i=0; i<len; ++i) 
            tmp[i]=(*str)[len-i-1];    // <<
    
         tmp[i]=0; 
         swap(str, &tmp); 
         free(tmp);   
    }
    
    int main()
    {
                char* abc = new char[4];
                strcpy(abc,"abc");
                reverse(&abc);
    
        return 0;
    }
    

    Compiliert ohne Fehler und macht was es soll.

    mfg



  • gerie schrieb:

    Compiliert ohne Fehler...

    das ist gelogen.
    ich bin zwar kein c-compiler, aber nur beim angucken sehe ich schon mindestens 2 fehler...
    🙂



  • muss natürlich

    char* abc = malloc (4);
    

    heissen, wir sind ja hier im C-Forum!



  • gerie schrieb:

    void reverse(char **str) 
    { 
         int len=strlen(*str); 
         char *tmp=(char*) malloc(len+1);    // type cast ist unnötig
         if(NULL==tmp) 
              exit(1);                       // besser: return 
         int i;                              // muss nach oben, sonst error
          
         for(i=0; i<len; ++i) 
            tmp[i]=(*str)[len-i-1];    
          
         tmp[i]=0; 
         swap(str, &tmp);                    // ein einfaches 'free(*str); *str=tmp;'... 
         free(tmp);                          // ...tut's auch. brauchst kein swap
    }
    


  • ok so klappst endlich 😃 , was mich aber noch interessieren würde:
    @ten: warum gibt das int i; einen error und was wäre denn die viel einfachere lösung?



  • c-newb schrieb:

    @ten: warum gibt das int i; einen error

    man kann nicht einfach variablen mitten im code anlegen. höchstens in einem neuen anweisungsblock {...}.

    c-newb schrieb:

    und was wäre denn die viel einfachere lösung?

    z.b. sowas:

    // 'out' muss auf ein array zeigen, das mindestens so gross ist strlen(in)+1 
    void reverse (char *in, char *out)
    {
        size_t l = strlen(in);
        out[l] = 0;
        while (*in)
            out[--l] = *in++; 
    }
    
    // dreht und kopiert den string zurück
    // geht natürlich nicht mit stringliteralen ;)
    void reverse_source (char *in)
    {
        char *p = malloc (strlen(in)+1);
        if (p)
        {
            reverse (in, p);
            strcpy (in, p);
            free (p);
        }
    }
    

    🙂



  • oder einfach ohne temporaer-string.



  • ten schrieb:

    c-newb schrieb:

    @ten: warum gibt das int i; einen error

    man kann nicht einfach variablen mitten im code anlegen. höchstens in einem neuen anweisungsblock {...}.

    naja, seit C99 stimmt das nicht mehr...

    Greetz, Swordfish


Anmelden zum Antworten