Anzeige:
Ergebnis 1 bis 10 von 10

Thema: C: array als rückgabe wert eine funktion

  1. #1
    Registrierter Benutzer
    Registriert seit
    04.10.2003
    Beiträge
    11

    C: array als rückgabe wert eine funktion

    ich habe Follgendes problem:
    ich möchte das eine funktion ein char array, dessen Grösse ich nicht kenne, zurückgibt.
    ich habe also vollgendes programm:

    Code:
    char *testArray(){
    char *a = "asdf";
    return a;
    }
    
    main() {   
       char *b = testArray();
       printf("%s",b);   
    }
    wenn ich nun aber diesen code schreibe, und das muss ich:

    Code:
    char *testArray(){
    char *a = {'a','s','d','f','\0'};
    return a;
    }
    
    main() {   
       char *b = testArray();
       printf("%s",b);   
    }
    habe ich zum einen diese compile warnings:

    Code:
    hello.c: In function `testArray':
    hello.c:55: warning: initialization makes pointer from integer without a cast
    hello.c:55: warning: excess elements in scalar initializer
    hello.c:55: warning: (near initialization for `a')
    hello.c:55: warning: excess elements in scalar initializer
    hello.c:55: warning: (near initialization for `a')
    hello.c:55: warning: excess elements in scalar initializer
    hello.c:55: warning: (near initialization for `a')
    und beim ausführen ein Segmentation fault. Warum? wie kann ich machen das es funktioniert?
    Geändert von Asraniel (06-04-2005 um 16:41 Uhr)

  2. #2
    Registrierter Benutzer Avatar von Boron
    Registriert seit
    07.01.2002
    Beiträge
    827
    Das hier lesen: http://www.mrunix.de/forums/showthread.php?t=38555

    Und zum Segfault:
    du legst den String ja lokal in der Funktion an.
    Beim Verlassen der Funktion wird der String gelöscht.
    Da du den String aber außerhalb der Funktion weiter verwenden willst zeigt "b" in einen Speicherbereich, wo offiziell nichts ist.
    Der Segfault macht das unmissverständlich klar.
    Gruß Boron (der sich oft wegen mieser Rechtschreibung anderer die Augen reiben muss)

    LINUX IS LIKE AN INDIAN TENT: NO GATES, NO WINDOWS AND AN APACHE INSIDE!
    Hardware Monitoring unter Linux -> http://santafu.sourceforge.net (Temperaturen, Lüfterdrehzahlen und Spannungen)

  3. #3
    Registrierter Benutzer
    Registriert seit
    04.10.2003
    Beiträge
    11
    danke, mein problem ist nur, dass das erste beispiel funktioniert und das zweite nicht, nur dass beide für mich das genau gleiche ist (bin java coder ;-) )

    edit: lese grad die FAQ die dort gelinkt wurde, verstehe schon etwas mehr. nur dass ich nicht weiss wie ich es denn nun machen soll. Weil das hier:

    Code:
    char *testArray(){
    char a[] = {'a','s','d','f','\0'};
    return &a;
    }
    
    main() {   
       char *b = testArray();
       printf("%s",b);   
    }
    geht auch nich, follgende errors kommen beim kompilieren

    Code:
    hello.c: In function `testArray':
    hello.c:56: warning: return from incompatible pointer type
    hello.c:56: warning: function returns address of local variabl
    edit2: ohne das & beim return gehts auch nicht wesentlich besser
    Geändert von Asraniel (06-04-2005 um 16:47 Uhr)

  4. #4
    Registrierter Benutzer
    Registriert seit
    18.03.2005
    Beiträge
    211
    naja, du gibts nen zeiger aufn array zurueck, was nach beendigung der funktion im nirvana verschwindet .....

    gibt paar regeln, an die man sich halten sollt. ....
    eine iss zum beispiel, das man speicher immer im gleichen block allocieren und wieder deallocieren sollte .... oder im Konstructor / Destructor ner klasse ...

    Willst unbedingt den String als rueckgabewert, dann solltes ne klasse verwenden ..... (falls c++ verwendest)

    C-Funktionen gaengiger API's geben nie den allocierten speicher als Rueckgabewert zrueck (sei denn es ist eine spezialisierte funktion nur zum allocieren von gewissen spiecher) sondern schreiben auf vorhandenen Bereichen ......

    mesit werden die funktionen, wenn sie viel speicher beschreiben koennten, in 2 modis betrieben .....

    int writeArray(int * anz,char * buffer);

    einmal setzt buffer (den zeiger) auf null, so dass deine funktion weiss dass sie nich auf den speicher schreiben soll ... dan gibt sie die benoetigte Groesse zurueck, in dem sie den an die sspeicherstelle von anz schreibt ....
    und einmal gibst ihr nen reservierten zeiger, und in anz die Groesse des allociertern bereiches .... so das sie weis wie viel sie max schreiben kann ....

    Hat den vorteil, das der benutze der funktionen sowohl statisch auf Geschwindigkeit, oder auch dynamisch auf verwendeten speicher optimieren kanne .....

    1. version saehe so aus ...

    const int MaxBufferSize = 1024;
    int Anz = MaxBufferSize ;
    char buffer[MaxBufferSize ]; // soll fuer alle anwendungsfaelle reichen ..... spart die kosten einer dynamischen allocation ....


    ires = writeArray(&Anz ,buffer); // hier wird ins array nu geschrieben

    oder version 2 .....

    int anz = 0;

    ires = writeArray(&Anz ,NULL); // statt NULL 0 nehmen falls nichdefiniert ...
    // in Anz steht nu die benoetigte groesse
    char * buffer = (char *) malloc(anz*sizeof(char));
    ires = writeArray(&Anz ,buffer); // hier schreibt er nu wirklich ....

    // nach dem anwenden loeschen ned vergessen

    free(buffer);

    Ciao ...

  5. #5
    Registrierter Benutzer Avatar von panzi
    Registriert seit
    04.05.2001
    Ort
    Kottingbrunn
    Beiträge
    609
    sizeof(char) ist AFAIK per definition 1.
    Intel Core 2 Duo CPU 2.66GHz; Nvidia GeForce 8 8800 GTS; 4GB RAM; Fedora 12; KDE-testing

  6. #6
    Registrierter Benutzer
    Registriert seit
    04.10.2003
    Beiträge
    11
    RHBaum:
    ich habe alles versucht, aber es geht irgendwie nicht!

    Code:
    void testArray(char *buffer){
    buffer = "asdf";
    }
    
    main() {   
       char buffer[20];
       testArray(&buffer);
       printf("%s",buffer);   
    }
    das sollte doch gehen? oder hab ich was nicht verstanden? ohne das & geht es auch nicht

  7. #7
    Registrierter Benutzer Avatar von panzi
    Registriert seit
    04.05.2001
    Ort
    Kottingbrunn
    Beiträge
    609
    Zitat Zitat von Asraniel
    RHBaum:
    ich habe alles versucht, aber es geht irgendwie nicht!

    Code:
    void testArray(char *buffer){
    buffer = "asdf";
    }
    
    main() {   
       char buffer[20];
       testArray(&buffer);
       printf("%s",buffer);   
    }
    das sollte doch gehen? oder hab ich was nicht verstanden? ohne das & geht es auch nicht
    Also das geht schon garnicht.
    Das geht z.B., aber ACHTUNG, der String liegt da im .TEXT Block und ist somit read-only:
    Code:
    void get_string(const char ** buffer){
       *buffer = "asdf";
    }
    
    int main() {   
       const char * str;
       get_string( &buffer );
       puts( string ); 
    }
    Oder das:
    Code:
    char * get_new_string() {
       char * str = malloc( XXX );
       if( str ) strncpy( str, XXX, XXX );
       return str;
    }
    
    int main() {
       char * str = get_new_string();
    
       puts( str );
       
       /* WICHTIG! */
       free( str );
       return 0;
    }
    Oder:
    Code:
    void get_string( char * buf, sitze_t size ) {
       strncpy( buf, XXX, size );
    }
    
    int main() {
       char buf[ XXX ];
    
       get_string( buf, XXX );
       puts( str );
       
       return 0;
    }
    Intel Core 2 Duo CPU 2.66GHz; Nvidia GeForce 8 8800 GTS; 4GB RAM; Fedora 12; KDE-testing

  8. #8
    Registrierter Benutzer
    Registriert seit
    18.03.2005
    Beiträge
    211
    @panzi
    sizeof(char) ist AFAIK per definition 1.
    Mir ist keine Impl bekannt wo es nich so ist, aber sag niemals nie :-)
    Zumal Dir sizeof in dem Fall keine kosten zur laufzeit beschert ... isses eigentlich egal :-) Stecks in die Kategorie Paranoia :-)

    @Asraniel
    Schau dir Strings noch mal genauer an ... und Zeiger. Erst wenn Dir selber klar iss, wass Du in deinem Beispiel genau tust, solltest mit anderen Sachen weitermachen ....
    Grad wenn C Programmieren willst, muss Dir das tief ins Hirn eigebrannt sein ... und "Fehler" durfen nur noch vom Vertippern, bzw unachtsamkeiten herkommen, aber keine logischen Zweifel mehr sein :-) Sonst kommst in Teufels Kueche !

    Nur als Tipp, man kann Zeiger kopieren, und man kann den Inhalt kopieren, auf den Zeiger zeigen, und es ist was total unterschiedliches :-)
    Wenn du also Daten auf ein array kopieren willst, wird es mit dem kopieren eines einfachen datentypes nicht erledigt sein, sondern du musst Hilfsfunktionen zu rate ziehen ... memcpy, strcpy, strncpy ... etc sind solche Kandidaten ....

    Ciao ...

  9. #9
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Zitat Zitat von RHBaum
    @panzi

    Mir ist keine Impl bekannt wo es nich so ist, aber sag niemals nie :-)
    Zumal Dir sizeof in dem Fall keine kosten zur laufzeit beschert ... isses eigentlich egal :-) Stecks in die Kategorie Paranoia :-)
    Soviel ich weiss hat panzi recht - das Byte in C ist per Definition die Grösse von einem Char (und soviel ich weiss sogar diesen Weg rum definiert)

    http://www.eskimo.com/~scs/C-faq/q7.8.html

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  10. #10
    Registrierter Benutzer
    Registriert seit
    18.03.2005
    Beiträge
    211
    Im standard steht auch viel ... progge mal mit VC 6.0 ... iss das ueberhaupt C++ ? :-)

    Hat nix mit dem char und byte zu tun ... ich propagier ja auch ned, dass ihrs machen sollt wie gesagt, es kostet nichts also lass ich es stehen ...

    Da ich normal viel mit templates mache, sind typen bei mir eh oft relativ, also verwende ich sehr oft sizeof ... iss also eher nen reflex ...

    Wieso muss ich mich dafuer eigentlich rechtfertigen ? Warum stosst ihr euch so an dem sizeof(char) ???

    Ciao ...

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •