Forum: PC-Programmierung Problem mit realloc?


von heinz (Gast)


Lesenswert?

Hallo,
ich versuch mich gerade an einem Slicer für STL Modelle und hab ein 
Problem
mit der Speicherallocation

OS ist Windows XP
Compiler PellesC
Sprache C

Bis auf den Fehler alles rausgelöscht

aufgerufen wird aus WindowProc durch Tastendruck

1
typedef struct{
2
  float xn,yn,zn;
3
  float x1,y1,z1;
4
  float x2,y2,z2;
5
  float x3,y3,z3;
6
} TRIANGLE;
7
8
9
10
int ReadSTL(void){
11
int i,max;
12
TRIANGLE *t=NULL;
13
14
  max=2000;
15
  t=malloc(max*sizeof(TRIANGLE));
16
17
  max=30000;
18
  realloc(t,max*sizeof(TRIANGLE));
19
  if (t==NULL) return -1;
20
  for (i=0;i<=2000;i++){
21
    t[i].z3=(FLOAT)5.5;
22
  }
23
  return 0;
24
}

gibt beim schreiben auf t[i].z3 (i=12) eine Zugriffsverletzung
Wenn ich den realloc rausnehm funktioniert es.
Was sehe ich da nicht?

Gruss heinz

: Verschoben durch Moderator
von Peter II (Gast)


Lesenswert?

heinz schrieb:
> Wenn ich den realloc rausnehm funktioniert es.
> Was sehe ich da nicht?

schau doch mal in der doku nach wie realloc funktioniert, achte dabei 
mal auf das "return" der funktion!

von heinz (Gast)


Lesenswert?

laut Doku sollte der realloc einen Nullpointer zurückgeben wenn er fehl 
schlägt.

Ich kann mit dem Debugger verfolgen, dass der in dem Programmteil bleibt 
bis zum bitteren Ende

Das wollte ich eigentlich in "PC Hard & Software" posten, kann das 
jemand verschieben?

von Stefan E. (sternst)


Lesenswert?

heinz schrieb:
> laut Doku sollte der realloc einen Nullpointer zurückgeben wenn er fehl
> schlägt.

Und du wertest die Rückgabe überhaupt nicht aus.

von Peter II (Gast)


Lesenswert?

heinz schrieb:
> laut Doku sollte der realloc einen Nullpointer zurückgeben wenn er fehl
> schlägt.

und was was liefert er zurück wenn es keinen fehler gibt?

tipp: wie soll sich denn t ändert, wenn du ihn an eine funktion 
übergibst?

von Bernhard M. (boregard)


Lesenswert?

Hallo,

realloc kann den übergebenen Wert von t nicht ändern, deshalb gibt es 
den neuen Wert zurück.
Also so anwenden:
1
typedef struct{
2
  float xn,yn,zn;
3
  float x1,y1,z1;
4
  float x2,y2,z2;
5
  float x3,y3,z3;
6
} TRIANGLE;
7
8
9
10
int ReadSTL(void){
11
int i,max;
12
TRIANGLE *t=NULL;
13
14
  max=2000;
15
  t=malloc(max*sizeof(TRIANGLE));
16
17
  max=30000;
18
  t = realloc(t,max*sizeof(TRIANGLE));
19
  if (t==NULL) return -1;
20
  for (i=0;i<=2000;i++){
21
    t[i].z3=(FLOAT)5.5;
22
  }
23
  return 0;
24
}

von Karl H. (kbuchegg)


Lesenswert?

heinz schrieb:
> laut Doku sollte der realloc einen Nullpointer zurückgeben wenn er fehl
> schlägt.

Und was liefert er, wenn er nicht fehl schlägt?

von heinz (Gast)


Lesenswert?

@Bernhard M
Autsch - manchmal bin blind
Danke, auch an die anderen

heinz

von Peter II (Gast)


Lesenswert?

Bernhard M. schrieb:
> Bernhard M.
>         (boregard)

schechtest Beispiel. Denn wenn realloc NULL zurückliefert, kannst du 
deinen alten speicher nicht mehr freigeben!

http://msdn.microsoft.com/en-us/library/xbebcx7d.aspx

von heinz (Gast)


Lesenswert?

Das wahr schon klar

t1 = realloc(t,max*sizeof(TRIANGLE));
if (t1!=NULL)
  t=t1
else
...

Ich hab nur nicht gemerkt dass ich überhaupt kein lvalue hab.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Es gibt noch ein weiteres potentielles Problem, nämlich das Alignment 
eines Arrays von TRIANGLE. Daher kann das Array mehr Speicher benötigen 
als max*sizeof(TRIANGLE).

Die derzeitige Definitoin von TRIANGLE dürfte das Problem zwar nicht 
aufweisen, wohl jedoch:
1
typedef struct{
2
  float xn,yn,zn;
3
  float x1,y1,z1;
4
  float x2,y2,z2;
5
  float x3,y3,z3;
6
  uint8_t a;
7
} TRIANGLE;

von Peter II (Gast)


Lesenswert?

Andreas Schweigstill schrieb:
> Es gibt noch ein weiteres potentielles Problem, nämlich das Alignment
> eines Arrays von TRIANGLE. Daher kann das Array mehr Speicher benötigen
> als max*sizeof(TRIANGLE).

nein das dürfte NIE ein problem werden. Dann dann könnte man überhaupt 
keine Programme schreiben.

ein index zugriff ist immer

p[i] = p + (i * sizeof(p))

entweder wird durch das Alignment das sizeof mit größer oder halt nicht. 
Dann gibt es auch keine lücken.

von Hans (Gast)


Lesenswert?

Peter II schrieb:
> p[i] = p + (i * sizeof(p))

p[i] = *(p + (i * sizeof(p)))

dereferenzieren nicht vergessen :-)

von dadada (Gast)


Lesenswert?

Hans schrieb:
> p[i] = *(p + (i * sizeof(p)))
>
> dereferenzieren nicht vergessen :-)

Das ist doch nicht richtig. Richtig ist

p[i]=*(p+i)

das 'sizeof' passiert automatisch.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.