[C++]Dynamisch geallocceerd array wijst naar bestaand object

Pagina: 1
Acties:

  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Topicstarter
Ik zit me hier helemaal kapot te zweten op een fijne SIGBUS, waar ik geen touw aan weet te knopen omdat de GDB output zichzelf compleet tegenspreekt.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
  // Init code for visible & lights (in case new matrices are created after last call)
  if(numObjects < (int) matrices.size()) {
    for(i = 0; i < numObjects; i++) {
      delete visible[i];
      delete lights[i];
    }
    if(visible != NULL) delete visible;
    if(lights != NULL) delete lights;
    numObjects = matrices.size();
    visible = new int*[numObjects];
    lights = new GLfloat*[numObjects];
    for(i = 0; i < numObjects; i++) {
      visible[i] = new int[matrices[i]->model->triangles->numTriangles];
      lights[i] = new GLfloat[4];
    }
  }
  // Fills lights array with translated values (light relative to object)
  light->translateLight(matrices, lights);

  // Walk through planes, see if they're lit or not
  for(i = 1; i < matrices.size(); i++) {
    Matrix *firstMatrix = matrices[0];
    Matrix *secondMatrix = matrices[1];
    Matrix *lastMatrix = matrices[2];
    Matrix *curMatrix = matrices[i];
    Model *curModel = curMatrix->model;
    for(j = 0; j < curModel->triangles->numTriangles; j++) {
      // normal calc is fixed to the cube model, temp for debugging
      GLfloat *cur_nor = curModel->normals->normals + (j / 2)*3;
      GLfloat cur_pla = curModel->shadowModel->planeDistances[j];
      GLfloat side = cur_nor[0] * lights[i][0] + 
                     cur_nor[1] * lights[i][1] + 
                     cur_nor[2] * lights[i][2] + 
                     cur_pla * lights[i][3];
      if(side > 0)
        visible[i][j] = 1;
      else
        visible[i][j] = 0;
    }
  }

matrices is een vector ala <Matrix*>, en in de rest van de for loop worden de matrices niet gewijzigd (alleen maar uitgelezen). De app wordt op het moment geinitialiseerd met drie matrices, zodat ik zeker weet dat er echt drie zijn (vandaar de first/second/last, dit om even in GDB de locaties te kunnen zien). Deze verwijzen allemaal naar hetzelfde Model, dus deze moet hetzelfde blijven gedurende de loop.

Welnu, als ik i=1 doe, en dus 1 & 2 benader, loopt alles goed af, as in:
matrix[1] = secondMatrix, Model* verwijst naar het model, matrix[2] = lastMatrix, Model* verwijst nog steeds naar het model.
Alleen als ik i=0 doe (en dus de eerste matrix benader) gebeurd er het volgende:
matrix[0] = firstMatrix, Model* is het model, dan matrix[1] = secondMatrix, en veranderd Model* in 0x1. 8)7

Als ik dan het volgende doe:
C++:
1
2
3
4
5
6
7
8
9
10
  for(i = 0; i < numObjects; i++) {
    Matrix *firstMatrix = matrices[0];
    Model *firstModel = matrices[0]->model;
    Matrix *secondMatrix = matrices[1];
    Model *secondModel = matrices[1]->model;
    Matrix *lastMatrix = matrices[2];
    Model *lastModel = matrices[2]->model;

    Matrix *curMatrix = matrices[i];
    ...

Zie ik secondModel ook naar 0x1 springen (van het correcte adres) het moment dat de for voor de tweede keer wordt uitgevoerd. Indien ik de for begin met i=1 gebeurd dit niet.

Het enige wat ik me kan bedenken is dat er ergens toch iets gewijzigd wordt aan de matrices in de andere classes, maar ten eerste zijn er geen functies die iets wijzigen, en ten tweede roep ik niet eens functies aan van andere classes in de for. :/
Het andere wat me binnen schiet is dat ik 0 || 1 wegschrijf in 'visible', vandaar dat ik die init code ook even heb geinclude. Als ik dat stuk comment werkt het namelijk wel, dus ik heb het idee dat ik gewoon over m'n geheugen zit weg te schrijven ipv m'n eigenlijke visible array. Maar ik zie daar niks fout in? :X

Heeft iemand suggesties wat ik moet controleren om de fout te vinden? Ik ben compleet clueless. :|

Edit: Ik bedenk me net dat m'n topic titel redelijk vaag is. Als een mod een betere omschrijving weet mijn dank hiervoor Complete stickie is hiervoor. Oops, even gemist. "[C++] Dynamisch geallocceerde array wijst naar bestaand object?" misschien? :>

Edit2: Even als followup: Wanneer ik de volgende regel in m'n code plant;
C++:
1
int *foo = visible[i];

Dan zie ik dat dit naar hetzelfde adres verwijst als m'n tweede matrix indien i=0. Vaagheid :|
Oh en nog even hoe alles gedeclareerd is;
C++:
1
2
3
4
5
6
7
8
9
10
class Shadow {
  public:
    int **visible;
    GLfloat **lights;
    int numObjects;
    
    Shadow(void) { visible = NULL; numObjects = 0; }
    void calcShadow(Light *light, std::vector<Matrix*> matrices);
    void drawShadow(Light *light, std::vector<Matrix*> matrices);
};

[ Voor 20% gewijzigd door wacco op 26-07-2006 18:08 ]

Spolap: Interactive webcomic


  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Topicstarter
Om het nog even te visualiseren, als ik dit doe in de init code:
C++:
1
2
3
4
5
6
    for(i = 0; i < numObjects; i++) {
      fprintf(stderr, "Iter:%d, Model_loc:%x, Old_visible:%x, ", i, (int) &matrices[i]->model, (int) visible[i]); 
      visible[i] = new int[matrices[i]->model->triangles->numTriangles];
      fprintf(stderr, "New_visible:%x\n", (int) visible[i]);
      lights[i] = new GLfloat[4];
    }

Krijg ik als output:
code:
1
2
3
4
5
6
[Session started at 2006-07-26 17:55:40 +0100.]
Iter:0, Model_loc:322da0, Old_visible:357b, New_visible:32c170
Iter:1, Model_loc:32c170, Old_visible:0, New_visible:35e4a0
Iter:2, Model_loc:3225a0, Old_visible:0, New_visible:360af0

wacco_engine has exited due to signal 10 (SIGBUS).

M'n new call geeft dus een referentie naar m'n bestaande object. Ik heb ook al even een try/catch gedaan op bad_alloc, maar die werd niet gegooid. :/

En als ik even het volgende in m'n code erbij zet;
C++:
1
2
3
4
5
6
7
8
9
/* Model.cpp */
Model::~Model(void) {
  delete triangles;
  delete normals;
  delete shadowModel;
  exit(5);
}
/* Matrix.h */
~Matrix(void) { exit(5); }

Dan gebeurt er helemaal niks. Dus die deconstructors worden nooit aangeroepen, aka; die objecten bestaan nog gewoon en m'n pointers zijn niet invalid. :/

Edit: Laatste (lichtelijk wanhopige) update, als ik maar twee matrices aanmaak via de volgende code, dan werkt het wel (maar met maar twee objecten dus).
C++:
1
2
3
4
5
Matrix *Scene::newMatrix(void) {
  Matrix *ret = new Matrix();
  matrices.push_back(ret);
  return ret;
}

De output is als volgt;
code:
1
2
3
4
5
[Session started at 2006-07-26 18:48:45 +0100.]
Iter:0, Model_loc:322da0, Old_visible:357b, New_visible:3612a0
Iter:1, Model_loc:32c170, Old_visible:0, New_visible:360a60

wacco_engine has exited with status 0.

Nog even voor de duidelijkheid; Model_loc is dus het adres van de pointer naar het model in de class Matrix, niet het model zelf. Old_visible had ik even erbij gezet om er zeker van te zijn dat ik dat niet per ongeluk als uninitialised pointer gebruikte.

[ Voor 47% gewijzigd door wacco op 26-07-2006 19:57 ]

Spolap: Interactive webcomic


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13-02 18:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Heb nog niet je hele posts doorgelezen, maar de eerste opmerking: arrays delete je met delete[], niet met delete

C++:
1
2
3
4
5
int * a = new int;
int * b = new int[23];

delete a;
delete[] b;

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Topicstarter
Yap, had ik ook al gespot en gefixed, maar hielp helaas niets. Het gaat al fout tijdens de eerste keer dat de class wordt aangeroepen wanneer de pointers nog NULL zijn en numObjects ook 0 is. Heel de delete calls worden nooit uitgevoerd voordat het al fout gaat. :/

Spolap: Interactive webcomic


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 21:33
Ik heb je code even bekeken en ik zie niet direct een fout.

Weet je heel zeker dat je de boel zonder optimalisaties compileert? Anders is de kans groot dat je in de debugger rare waarden tegenkomt, en dat maakt debuggen wel heel lastig.

Verder kun je eens kijken naar de call stack als je die signal krijgt. Waar gaat het precies fout?

  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Topicstarter
Ik heb eens zitten kijken in de IDE (Xcode) en kwam iets tegen dat MallocDebug heette. Dat klonk erg interessant, dus ik startte het op. En toen startte ook m'n applicatie weer zonder errors. :| Maar zonder de MallocDebug tool werkt het dus niet.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Session started at 2006-07-26 20:52:45 +0100.]
Iter:0, Model_loc:322da0, Old_visible:357b, New_visible:32c170
Iter:1, Model_loc:32c170, Old_visible:0, New_visible:3600d0
Iter:2, Model_loc:3225a0, Old_visible:0, New_visible:360110

wacco_engine has exited due to signal 10 (SIGBUS).
[Session started at 2006-07-26 20:52:52 +0100.]
(11403) malloc: recording stacks using standard recorder
libMallocDebug[11403]: initializing libMallocDebug on thread d03
libMallocDebug[wacco_engine-11403]: free: target application attempted to free pointer 0x55555555 that is not pointing to a malloc block.  The address is not in memory used by the heap.
libMallocDebug[wacco_engine-11403]: If you run under the debugger, it will automatically break here.
Iter:0, Model_loc:1711b90, Old_visible:0, New_visible:174c010
Iter:1, Model_loc:1713570, Old_visible:0, New_visible:174c240
Iter:2, Model_loc:1713600, Old_visible:0, New_visible:174c380

wacco_engine has exited with status 0.

Die 'automatically break' van de debugger gebeurd dus nooit, en ik vraag me dan ook sterk af waar ik iets probeer te free()'en met dat adres. Ik roep die hele functie nergens aan! :(

Edit, van de apple docs
Usually a crash results from subtle memory problems, such as referencing freed memory or dereferencing pointers found outside an allocated buffer. Check suspected buffers of memory with the memory-buffer inspector (see ?Analyzing Raw Memory?). If your program is referencing memory at 0x55555555, then it is referencing freed memory.
Great! Ik heb dus *of* een free() ergens (waar ik al de hele dag naar aan het zoeken ben) *of* een buffer overflow (die ik dus ook nergens zie, en welke alleen maar zichtbaar gemaakt kan worden bij het verschil in objecten in m'n STL vector)... :'(

[ Voor 22% gewijzigd door wacco op 26-07-2006 22:02 ]

Spolap: Interactive webcomic


  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Topicstarter
Found it! Jeez...

Zie hoe in de constructor lights niet naar NULL wordt geinitialiseerd? Dat (waarschijnlijk) verknoeide m'n heap, en dat werd (klaarblijkelijk) zichtbaar compleet ergens anders. Gewoon 4+ uur overheen zitten staren :( :(

Maar het werkt weer! *Doet dansje*

(En nou heb ik een biertje verdient.. Pfff)

Spolap: Interactive webcomic

Pagina: 1