Ist das erlaubt oder noch guter Programmierstil?



  • #include <stdio.h>
    
    int main()
    {
      char s[50] = "Dies ist ein langer Satz, der ist viel zu lang!\n\n";
      printf("%sAlso kürzen wir ihn!\n", s);
      s[24] = '.';
      s[25] = '\0'; // Abschneiden durch Nullbyte setzen.
    
      printf("\n%s\n\nJetzt ist es besser!\n", s);
    
      return 0;
    }
    

    Was passiert mit dem Speicherbereich zwischen s[26} und s[50]?
    Kann der mit z.B. mit malloc neu reserviert werden?
    Ist der Verloren oder noch reserviert?

    Und wie sehe es aus, wenn das char Array mit malloc reserviert worden wäre?
    Z.B. so:

    #include <string.h>
    #include <stdio.h>
    
    int main()
      char *ptr = (char *) malloc(48 * sizeof (char));
      if (ptr == NULL) {
        return 1;
      } else {
        strcpy(ptr, "Dies ist ein langer Satz, der ist viel zu lang!");
        printf("%s\n", ptr);
        printf("Länge = %i\n", (int) strlen(ptr));
    
        printf("Also kürzen wir ihn!\n\n");
        ptr[24] = '.';
        ptr[25] = '\0';
    
        printf("%s\n", ptr);
        printf("Länge = %i\n", (int) strlen(ptr));
        printf("Jetzt ist es besser!\n");
        free(ptr);
        ptr = NULL;
      }
      return 0;
    }
    


  • Abschneider schrieb:

    Was passiert mit dem Speicherbereich zwischen s[26} und s[50]?

    Was soll mit dem passieren?

    Abschneider schrieb:

    Kann der mit z.B. mit malloc neu reserviert werden?

    Äh.. nein. 1. ist er schon reserviert (und wird nicht freigegeben, nur weil man irgendwo eine 0 reinschreibt. Wär ja schlimm!) und 2. ist der Speicher vom Stack. 🙂

    Abschneider schrieb:

    Ist der Verloren oder noch reserviert?

    Erübrigt sich dann wohl.

    Abschneider schrieb:

    Und wie sehe es aus, wenn das char Array mit malloc reserviert worden wäre?

    Genau so. Der Speicher interessiert sich nicht für das, was du mit ihm machst. Du kannst ihn auch komplett mit Nullen füllen, deswegen wird er sich nicht in Luft auflösen. Das '\0' begrenzt nur die Stringlänge, ansonsten hat es keinen Effekt!
    Und somit kannst du dir auch gleich denken: Ja, das ist durchaus üblich und hat bestimmt nichts mit schlechtem Stil zu tun!



  • Es ist besser den Compiler diese Arbeit machen zu lassen, der kann besser zählen als du:

    char s[] = "Dies ist ein langer Satz, der ist viel zu lang!\n\n";
    

    Und deine Casts sind auch überflüssig.



  • Wutz schrieb:

    Und deine Casts sind auch überflüssig.

    strlen liefert aber ein size_t zurück. Und das ist ein unsigned Type.

    Er hätte besser %u benutzt.



  • Wutz schrieb:

    Und deine Casts sind auch überflüssig.

    Nein, sind sie nicht. strlen gibt size_t zurück, und das kann auch mal ein unsigned long sein.

    Es gibt in C99 einen Format-Spezifikator %z, der für size_t eingeführt wurde, aber in C90 braucht man hier einen Cast, um definiertes Verhalten zu erzeugen. Einfach

    printf("%i", strlen(foo)); // Kawumm!
    

    wäre ein Fehler und wird insbesondere auf Big-Endian-Architekturen, auf denen sizeof(int) < sizeof(long) ist, überraschende Ergebnisse liefern.

    Allerdings ist int womöglich nicht der beste Zieltyp. Ich würde

    printf("%lu", (unsigned long) strlen(foo));
    

    schreiben.



  • @Abschneider
    Die '\0' besagt nur, dass an dieser Stelle der Text zu Ende ist. Das hat nichts mit dem Array zu tun wo der Text drin steht.

    Im Übrigen machen die Library-Funktionen das auch nicht anders als du.

    In deinem ersten Beispiel kannst du das sogar mit sizeof() überprüfen.

    #include <stdio.h>
    
    int main()
    {
      char s[] = "Dies ist ein langer Satz, der ist viel zu lang!\n\n";
      printf("sizeof(s)= %u, strlen(s) = %u\n", (unsigned)sizeof(s), (unsigned)strlen(s));
    
      printf("%sAlso kürzen wir ihn!\n", s);
      s[24] = '.';
      s[25] = '\0'; // Abschneiden durch Nullbyte setzen.
      printf("sizeof(s)= %u, strlen(s) = %u\n", (unsigned)sizeof(s), (unsigned)strlen(s));
    
      printf("\n%s\n\nJetzt ist es besser!\n", s);
    
      return 0;
    }
    

Anmelden zum Antworten