Josef: / C: Pointer "überprüfen.."

Hallo.

Folgender Beispielcode:

  
  
#include <stdio.h>  
  
typedef struct foo  
{  
  const char *hello;  
} foo_t;  
  
void my_function(foo_t *p_foo)  
{  
  if (p_foo->hello)  
    printf("TRUE\n");  
  else  
    printf("FALSE\n");  
}  
  
int main()  
{  
  foo_t my_foo;  
  
  my_function(&my_foo);  
  
  return 1;  
}  
  

Der Pointer my_foo.hello ist ja nicht initialisiert. Er verweist also auf eine beliebige Stelle im Speicher. Da er nicht auf NULL zeigt, ist er TRUE. Wie überprüfe ich, a) ob ein Pointer auf eine valide (von mir zugewiesene) Adresse zeigt oder b) wie initialisiere ich alle Pointer default mit NULL. (Angenommen, das struct hat n Elemente, möchte ich ja nicht n Elemente auf NULL setzen)

Thx.

  1. Hi,

    Der Pointer my_foo.hello ist ja nicht initialisiert. Er verweist also auf eine beliebige Stelle im Speicher. Da er nicht auf NULL zeigt, ist er TRUE.

    soweit richtig.

    Wie überprüfe ich, a) ob ein Pointer auf eine valide (von mir zugewiesene) Adresse zeigt

    Gar nicht. Du kannst bestenfalls die Speicherverwaltung des Betriebssystems fragen, ob ein Lese- oder gar Schreibzugriff über diesen Zeiger erlaubt ist (AFAIR bietet das Windows-API entsprechende Testfunktionen, ich finde aber im Augenblick nichts Passendes).

    oder b) wie initialisiere ich alle Pointer default mit NULL. (Angenommen, das struct hat n Elemente, möchte ich ja nicht n Elemente auf NULL setzen)

    Easy:  memset(&var, 0, sizeof(var));
    Alternativ bei dynamisch vom Heap angefordertem Speicher: calloc() anstatt malloc() verwenden.

    So long,
     Martin

    --
    Man soll den Tag nicht vor dem Abend loben.
    Und den Mann nicht vor dem Morgen.
      (alte Volksweisheit)
    1. oder b) wie initialisiere ich alle Pointer default mit NULL. (Angenommen, das struct hat n Elemente, möchte ich ja nicht n Elemente auf NULL setzen)

      Easy:  memset(&var, 0, sizeof(var));

      Danke. Eine "Manchmal sieht man den Wald vor.."-Situation.

      1. Hallo,

        oder b) wie initialisiere ich alle Pointer default mit NULL. (Angenommen, das struct hat n Elemente, möchte ich ja nicht n Elemente auf NULL setzen)
        Easy:  memset(&var, 0, sizeof(var));
        Danke. Eine "Manchmal sieht man den Wald vor.."-Situation.

        Zitat #1555 ;-)

        Schönes Wochenende,
         Martin

        --
        Lieber blau machen, als sich schwarz ärgern.
    2. Hallo Martin,

      oder b) wie initialisiere ich alle Pointer default mit NULL. (Angenommen, das struct hat n Elemente, möchte ich ja nicht n Elemente auf NULL setzen)

      Easy:  memset(&var, 0, sizeof(var));

      Weitere Alternative für den Stack:

      foo_t my_foo = { NULL };

      bzw. für kompliziertere Strukturen:

      typedef struct bar_s {  
        int a;  
        int b;  
        double c;  
        void *d;  
      } bar_t;
      

      bar_t my_bar = { 0, 0, 0.0, NULL };

      bzw. auch erlaubt ist (aber wird von verschiedenen Compilern zurecht mit einer Warnung quittiert):

      bar_t my_bar = { 0 };

      (Wenn man nur { 0 } schreibt heißt es, alle Felder werden mit 0 initialisiert.)

      Da letzteres schlechter Stil ist, ersteres aber von der Strukturdefinition abhängt, empfiehlt es sich, ein Makro direkt neben der Struktur zu definieren:

      typedef struct bar_s {  
        int a;  
        int b;  
        double c;  
        void *d;  
      } bar_t;  
        
      #define BAR_T_INITIALIZER  { 0, 0, 0.0, NULL }
      

      Und dann:

      bar_t my_bar = BAR_T_INITIALIZER;

      Je nach Compiler kann das schneller als memset() sein, muss aber nicht, da in neueren Compilern memset() oftmals eine eingebaute interne Funktion ist, die durch effizienten Assembler-Code an genau der Stelle ersetzt wird. Ist daher wohl Geschmackssache, was man nimmt.

      Viele Grüße,
      Christian

      --
      Mein "Weblog" [RSS]
      Using XSLT to create JSON output (Saxon-B 9.0 for Java)
      »I don't believe you can call yourself a web developer until you've built an app that uses hyperlinks for deletion and have all your data deleted by a search bot.«
                  -- Kommentar bei TDWTF
      1. Hallo Christian,

        Easy:  memset(&var, 0, sizeof(var));
        Weitere Alternative für den Stack:
        foo_t my_foo = { NULL };

        nicht nur für den Stack, also für lokale Variablen, sondern auch für initialisierte globale Daten.

        typedef struct bar_s {

        int a;
          int b;
          double c;
          void *d;
        } bar_t;

        
        >   
        > bzw. auch erlaubt ist (aber wird von verschiedenen Compilern zurecht mit einer Warnung quittiert):  
        > `bar_t my_bar = { 0 };`{:.language-c}  
          
        Ja, ich erinnere mich an irgendwas wie "partially initialized".  
          
        
        > (Wenn man nur { 0 } schreibt heißt es, alle Felder werden mit 0 initialisiert.)  
          
        Das ist aber AFAIK nur für Arrays so festgelegt - oder gilt das auch für structs?  
          
        Ciao,  
         Martin  
        
        -- 
        F: Was ist schneller: Das Licht oder der Schall?  
        A: Offensichtlich der Schall. Wenn man den Fernseher einschaltet, kommt immer erst der Ton, und dann erst das Bild.  
        
        
        1. Hallo Martin,

          { 0 }
          Das ist aber AFAIK nur für Arrays so festgelegt - oder gilt das auch für structs?

          Zumindest alle mir bekannten Compiler schlucken es auch für structs - die meisten werfen aber (IMHO zurecht) Warnungen, dass man das eigentlich nicht tun sollte.

          Viele Grüße,
          Christian

          --
          Mein "Weblog" [RSS]
          Using XSLT to create JSON output (Saxon-B 9.0 for Java)
          »I don't believe you can call yourself a web developer until you've built an app that uses hyperlinks for deletion and have all your data deleted by a search bot.«
                      -- Kommentar bei TDWTF