Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C] free() array van struct geeft invalid pointer

Pagina: 1
Acties:

  • honda4life
  • Registratie: Januari 2007
  • Laatst online: 22:22
Hallo iedereen,

Als (dikke) amateur durf ik wel eens te programmeren in mijn vrije tijd.
Nu heb ik het volgend probleem:
Ik ontvang data, maar heb er geen idee van hoe veel records dit zullen zijn. Om dit wat gestructureerd te houden, heb ik een struct van de ontvangen data gemaakt, en alloceer ik deze dynamisch.
So far so good, alloceren; schrijven en lezen gaat zoals het hoort... de array leegmaken wat minder.
Wat doe ik hier verkeerd, vast iets simpel?

Ik heb me gebaseerd op volgende informatie (werkt trouwens perfect):
http://fydo.net/gamedev/dynamic-arrays

Ook ben ik aan het testen geslagen met vectoren zoals je ziet, nu ben ik wel ontzettend hard c en c++ aan het mengen, wat toch niet meer zo netjes is.

Edit: Misschien is het beter een fixed size array te voorzien die al m'n data kan bevatten, vermits ik het maximum wel kan berekenen.

Bedankt alvast!

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <iostream>

typedef struct {
    time_t datetime;
    float totalkWh;
    float watt;
}PVOutGet;

void ClearArray_get();
int AddToArray_get(PVOutGet item);

PVOutGet *records = NULL;
int num_records = 0;

int main()
{
    PVOutGet buffGet = {0};
    std::vector <PVOutGet> vecrec;
    for(int k=0; k < 1000; k++){
        //Some "random" data is inserted        
        buffGet.datetime = k;
        buffGet.totalkWh = (float) k;
        buffGet.watt = (float) k;
        AddToArray_get(buffGet);
        vecrec.push_back(buffGet);
    }   
    
    for (size_t i = 0; i < vecrec.size(); i++){ 
        printf("vecrec[%i]: %lu\n",i , vecrec[i].datetime);     
    }

    for (int j = 0; j < num_records; j++){  
        printf("records[%i]: %lu\n",j , records[j].datetime);
    }
    
    ClearArray_get();
    return 0;
}

int AddToArray_get(PVOutGet item)
{

    puts("AddToArray_get()");
    void *_tmp = realloc(records, (num_records + 1) * sizeof(PVOutGet));
    if (!_tmp)
    {
        puts("realloc() failed!");
        return -1;
    }
    records = (PVOutGet*)_tmp;
    records[num_records] = item;
    num_records++;
    return num_records;
}

void ClearArray_get()
{
    puts("ClearArray_get()");

    //Deallocate
    for (int i = 0; i <= num_records - 1; i++)
    {
        printf("free(records[%i])\n", i);       
        //Wrong here?
        free(&records[i]);
    }
    free(records);
    num_records = 0;
}

  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 22:47

Super_ik

haklust!

Waarom & op regel 69? de records[i] is toch al een pointer naar het gealloceerde geheugen?

[ Voor 7% gewijzigd door Super_ik op 05-03-2013 23:18 ]

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


  • honda4life
  • Registratie: Januari 2007
  • Laatst online: 22:22
compiler neemt dat niet aan.vermits niet (void *) dacht ik.
Denk dat ik ook een extra loop ga implementeren, zodat ik minder realloc's moet doen.

  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 22:47

Super_ik

haklust!

werkt het met de (void *) cast wel?, want dat is volgens mij wel je fout.

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


  • honda4life
  • Registratie: Januari 2007
  • Laatst online: 22:22
free(records[i])
test.c:69:18: fout: cannot convert ‘PVOutGet’ to ‘void*’ for argument ‘1’ to ‘void free(void*)’

free((void*)records[i])
test.c:69:24: fout: invalid cast from type ‘PVOutGet’ to type ‘void*

  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 22:47

Super_ik

haklust!

je array van pointers is ook niet echt op de mooiste manier geimplementeerd, maar bij je realloc doe je het zelfde truukje door een temp variabele tegebruiken. probeer dat maar eens te copieren voor je free.

array van pointers:
C:
1
2
3
PVOutGet *records[] = NULL; // array van pointers naar PVOutGets

**records = realloc(**records, bla);

https://www.google.com/search?q=c+dynamic+array+of+pointers

[ Voor 33% gewijzigd door Super_ik op 05-03-2013 23:40 ]

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


  • honda4life
  • Registratie: Januari 2007
  • Laatst online: 22:22
void *_tmp = records[i];
_tmp = records[i];
free(_tmp);

Zo dan? werkt nog niet.

Hou zou jij het dan doen zonder tijdelijke variabele?

  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 22:47

Super_ik

haklust!

kijk eens goed welke mallocs/reallocs en free's bij elkaar horen, je malloc helemaal geen PVOutGet item. toch probeer je deze wel te free'en

je gebruikt realloc alleen om je records te mallocen....

btw,
C:
1
int AddToArray_get(PVOutGet item) 

moet dat niet *item zijn?

[ Voor 35% gewijzigd door Super_ik op 05-03-2013 23:52 ]

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


  • HMS
  • Registratie: Januari 2004
  • Laatst online: 17-11 00:33

HMS

Je hebt toch maar een 1 dimensionale array? Waarom probeer je dan een 2 dimensionale array op te ruimen?

Moet dit perse in C of kan het ook C++ zijn? Anders gebruik je toch gewoon de vector?

Verwijderd

Of implementeer zelf een simpele Linked list :)

O wacht, je gebruikt al een vector. Dan ben je er toch al?

[ Voor 24% gewijzigd door Verwijderd op 06-03-2013 08:45 ]


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 23-11 13:12
HMS schreef op woensdag 06 maart 2013 @ 00:32:
Je hebt toch maar een 1 dimensionale array? Waarom probeer je dan een 2 dimensionale array op te ruimen?
Afgezien van het feit dat de code van geen kant klopt, zie ik nergens dat er een 2 dimensionaal array wordt opgeruimd?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • blackangel
  • Registratie: April 2002
  • Laatst online: 22-11 20:36
Het is eigenlijk best simpel, je probeert iets te free()en wat je niet (zelf) gealloceerd hebt met malloc.

Het element wat op regel 69 probeert te verwijderen, wordt in de array gestopt op regel 55. Maar op regel 55 doe plaats je een copy van de struct, niet een pointer naar het object. De free op regel 69 is dus overbodig, de copy wordt namelijk netjes verwijderd op regel 71 bij het free()en van de hele records.

  • epic007
  • Registratie: Februari 2004
  • Laatst online: 17-11 15:31
Lees eens goed wat 'realloc' nu eigenlijk doet: http://www.cplusplus.com/reference/cstdlib/realloc/.

Aan het eind van je programma heb je uiteindelijk maar één blok geheugen gealloceerd.

C:
1
free(records);

volstaat dus. Als je de keus hebt zou ik vector gebruiken en de helle malloc, free links laten liggen.

  • HMS
  • Registratie: Januari 2004
  • Laatst online: 17-11 00:33

HMS

farlane schreef op woensdag 06 maart 2013 @ 09:01:
[...]

Afgezien van het feit dat de code van geen kant klopt, zie ik nergens dat er een 2 dimensionaal array wordt opgeruimd?
Je hebt gelijk, wat ik bedoelde was het free() aanroepen op de elementen van de array en daarna de array zelf free()en.

  • honda4life
  • Registratie: Januari 2007
  • Laatst online: 22:22
Het is me gelukt, na een nachtje er over te slapen was het me plots veel duidelijker waar ik met bezig was.

Bedankt iedereen!
Pagina: 1