C - realloc() direkt verwenden

OP #2160648
Lesenswert?
• ▲
▼
Hallo,

ich möchte mir einen Schritt beim dynamischen Speicher allokieren 
sparen.
Indem ich calloc() weglasse und direkt realloc() verwende.
Mein Programm funktioniert auch soweit - ich möchte nur wissen ob es 
evtl. Randeffekte haben kann - da die korrekte Verwendung von realloc() 
ja zum erweitern eines schon vorhandnen Speichers ist!!

....
*ptr = NULL;

ptr = (char *) realloc( ptr, Size );

.....
Es funktioniert deswegen - weil der Pointer, an der Stelle wo der 
Speicher erweitert werden soll - auf NULL zeigt!??!

Hat da jemand Erfahrung?
#2161028
Lesenswert?
• ▲
▼
max .. schrieb:
> *ptr = NULL
[...]

> weil der Pointer, an der Stelle wo der
> Speicher erweitert werden soll - auf NULL zeigt!??!

Das macht deine Zeile oben aber nicht. Die schreibt, egal wohin der 
Pointer gerade zeigt, eine 0.
Der Pointer zeigt also anschliessend nicht auf die Speicherstelle NULL, 
sondern auf (irgend-)eine Speicherstelle, die die Zahl 0 enthält.
Gast #2161041
Lesenswert?
• ▲
▼
Εrnst B✶ schrieb:
> Das macht deine Zeile oben aber nicht. Die schreibt, egal wohin der
> Pointer gerade zeigt, eine 0.
> Der Pointer zeigt also anschliessend nicht auf die Speicherstelle NULL,
> sondern auf (irgend-)eine Speicherstelle, die die Zahl 0 enthält.

Seit wann denn? Dann würden ja Millonen LoC nicht mehr funktionieren.

Es geht auch
{ int *ptr = NULL;
  int i;
  int *pi = &i;

Dann zeigt ptr auf NULL und pi zeigt auf i.
#2161082
Lesenswert?
• ▲
▼
DirkB schrieb:
> Seit wann denn?

Schon immer?

> Dann würden ja Millonen LoC nicht mehr funktionieren.

Nö... bei neueren Betrübssystemen gibts da nen Segfault/GPF, der Fehler 
wird schnell gefunden und ausgebessert.

123gast schrieb:
> *ptr=NULL;
> char *ptr=NULL;

Aus dem Grund scheibe ich bei Pointer-Deklarationen gern das '*'-chen an 
den Typ. Also
1
  char x;
2
  char* ptr=NULL; // ptr zeigt auf NULL
3
  ptr=&x;         // ptr zeigt auf x;
4
  *ptr='a';       // x enthält jetzt 'a'
5
  ptr=NULL;       // ptr zeigt wieder auf NULL
6
  *ptr='b';       // Segfault

So ist auf einen Blick deutlich, ob ich einen Pointer anlege (int* z) 
oder ob ich einen Pointer dereferenziere (*z).

Nur
1
  int* a,b;
macht halt nicht das, was man vielleicht im ersten Moment erwarten 
würde.
Gast #2161099
Lesenswert?
• ▲
▼
DirkB schrieb:
> 123gast schrieb:
>> @DirkB
>> Guck mal genau hin, wo ist der Unterschied?
>
> Danke für die Brille.
Gerne. :-)

Noch eine (wie ich finde nicht ganz unwichtige) Anmerkung zu realloc():

Das hier
1
ptr = NULL; //KEIN STERN!
2
ptr = (char *) realloc( ptr, Size );
ist vollkommen in Ordnung, birgt aber die Gefahr von Speicherlecks:
1
ptr=NULL;
2
ptr=realloc(ptr,sz);
3
if(!ptr)
4
{
5
  ...
6
} 
7
//bisher alles OK, aber jetzt
8
if(sz_needed>sz) //wir brauchen mehr Platz!
9
{
10
  ptr=realloc(ptr,sz_needed); //GEFAHR
11
  if(!ptr)
12
  {
13
    ...
14
  }
15
}
16
//...
Wenn der zweite Aufruf von realloc aus Speichermangel fehlschlägt 
bekommt ptr den Wert NULL zugwiesen, der Pointer auf den ersten 
angeforderten Bereich verschwindet. Es ist also nicht mehr möglich 
diesen Speicher freizugeben -->Speicherleck.

OK, wenn man das Programm bei einem solchen Fehler mit exit(42) beendet 
ist das egal, im gegenteiligen Fall könnte das aber zum Problem werden.

Lösung:
1
char* ptr,ptr_tmp;
2
//...
3
//mehr Speicher bitte
4
ptr_tmp=realloc(ptr,sz);
5
if(!ptr_tmp)
6
{
7
  //Problem
8
}
9
else //Kann man weglassen wenn bei Problemen das Programm beendet wird
10
{
11
  ptr=ptr_tmp;
12
  //...
13
}
Gast #2161103
Lesenswert?
• ▲
▼
Oh Oh, ganz schlecht formuliert. :-(
>else //Kann man weglassen wenn bei Problemen das Programm beendet wird
Soll heißen: Die if-Abfrage bekommt keinen else-Zweig sondern es geht 
direkt darunter weiter. Die Zuweisung ist natürlich trotzdem nötig!
1
if(!ptr_tmp)
2
{
3
  //...
4
  exit(42);
5
}
6
ptr=ptr_tmp;
7
//...
Gast #2161785
Lesenswert?
• ▲
▼
Klaus Wachtler schrieb:
> 123gast schrieb:
>> Falsch:
>> char* ptr,ptr_tmp;
>> Richtig:
>> char* ptr, *ptr_tmp;
>
> genau deshalb schreibe ich das Sternchen immer vor den Namen, nicht
> hinter den Typ :-)

Ich schreibe (nicht nur) aus diesem Grund einfach gar keine solchen 
kombinierten Definitionen. Deine Schreibweise ist zwar die von den 
C-Erfindern vorgesehene, aber meiner Meinung nach wenig intuitive 
Variante. Das Sternchen ist Teil des Typs und nicht Teil des Namens.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren