[pic32, C]:variabele lengte struct array dynamisch alloceren

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • timberleek
  • Registratie: Juli 2009
  • Laatst online: 08-09 22:13
Hallo

Ik loop een beetje tegen een programmeerkennis muur aan |:( , hopelijk kunnen jullie mij hiermee helpen.
Ik wil diverse plaatjes inladen vanaf een sd kaart om op het juiste moment op een scherm te laten zien. Het gaat om teveel data om in ram te laten staan, dus moet het anders.

Nu heb ik per "schermelement" een struct met data over het element (bijvoorbeeld, afmetingen, beginlocatie etc). Echter is er van tevoren niet bekend hoe groot de array van element structs wordt. En daar gaat het mis voor mij.

Er zijn meerdere soorten elementen, maar ik houd het nu even bij 1.

De struct voor een plaatje heb ik als volgt gedefinieerd:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
typedef struct image_element
{
    unsigned char conditional;
    unsigned char datafield;
    unsigned char comparisonType;
    unsigned char compareValue;

    unsigned char *filename;
    unsigned char active;

    unsigned short xSize;
    unsigned short ySize;
    unsigned short xStart;
    unsigned short yStart;

}screen_image_element;


In de main routine wordt hiervoor een array gedeclareerd, maar doordat de benodigde lengte niet bekend is nog niet geinitialiseerd:

code:
1
screen_image_element image_elements[];


Mijn idee was als volgt:
code:
1
2
3
4
5
6
7
Een functie parst de data in een bestand naar een tijdelijke screen_image_element struct (dit werkt).
Als image_elements[] nog leeg is (wordt apart bijgehouden) wil ik hem dan initialiseren.
    idee 1:image_elements = tijdelijke_struct (met het idee dat het dan een 1-velds array wordt, maar werkt niet)
    idee2: image_elements = malloc(sizeof(tijdelijke struct)
             image_elements[0] = tijdelijke struct
    idee 3: image_elements = realloc(image_elements, sizeof(tijdelijke stuct)
               image_elements[0] = tijdelijke struct


Hier loopt het al stuk. Ik krijg het maar niet voor elkaar.
Voordat ik nog uren ga zitten staren, kan wat ik wil wel?
mijn programmeerkennis wordt hier duidelijk flink gestretcht. O-)

alvast bedankt
Tim

Acties:
  • 0 Henk 'm!

Verwijderd

Is het noodzakelijk dat een het een array is?
Anders zou je misschien beter kunnen gaan voor een (double) linked list?

Acties:
  • 0 Henk 'm!

  • timberleek
  • Registratie: Juli 2009
  • Laatst online: 08-09 22:13
Dat denk ik niet, ik ga me even inlezen op een linked list

Acties:
  • 0 Henk 'm!

Verwijderd

OK, succes!
Laat maar weten of het lukt?

Acties:
  • 0 Henk 'm!

  • Vaan Banaan
  • Registratie: Februari 2001
  • Niet online

Vaan Banaan

Heeft ook Apache ontdekt

Kun je niet gewoon een array van pointers maken en die uitbreiden?
Dus
C:
1
2
3
4
5
image_element *element = NULL;
image_element **elements = NULL;
int length_array = 0; 
int num_elements = 0;
const int num_expand = 16; /* Ik noem maar wat */

En dan dit in een loop, while, whatever:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* struct plaatje aanmaken */
element = malloc(sizeof(*element));
if (!element)
    return -1;
memset(element, 0, sizeof(*element));
/* vul je struct */
element->conditional = ...
element->datafield = ...

/* maak/realloc pointer array indien nieuw/vol */
if (num_elements == length_array) {
    elements = realloc(elements, (length_array + num_expand) * sizeof(*elements));
    if (!elements)
        return -1;
    /* zero het laatste deel */
    memset(elements + length_array, 0, num_expand * sizeof(*elements));
    length_array += num_expand;
}

/* Hang struct in pointer array */
elements[num_elements] = element;
num_elements++;
element = NULL;

En op het eind kun je dan alles vrijgegeven
C:
1
2
3
4
5
(for i = 0; i < num_elements; i++)
    free(elements[i]);
num_elements = 0;
free(elements};
elements = NULL;

[ Voor 3% gewijzigd door Vaan Banaan op 03-07-2015 17:20 ]

500 "The server made a boo boo"


Acties:
  • 0 Henk 'm!

  • ErikKo
  • Registratie: Mei 2009
  • Laatst online: 18:07

ErikKo

Rippie

Wat Vaan Banaan zegt lijkt me inderdaad wat je zoekt.
Geen idee in welke situatie je dit toepast, maar is het een optie om C++ te gebruiken?
Met cpp zou dit verhaal veel makkelijker (en minder foutgevoelig) zijn.

Edit: Impliciet bedoel ik hiermee C++ STL.

[ Voor 9% gewijzigd door ErikKo op 03-07-2015 16:53 ]


Acties:
  • 0 Henk 'm!

  • timberleek
  • Registratie: Juli 2009
  • Laatst online: 08-09 22:13
Het heeft even geduurd, maar ik heb het nu geïmplementeerd met een linked list. Dat werkt tot nu toe prima.
Een array van pointer zou ook kunnen inderdaad, maar is dat niet een beetje hetzelfde idee? Alleen heb je de pointers nu in een lijst ipv dat je er doorheen moet wandelen (wat in de applicatie geen probleem is aangezien toch alles iteratief wordt doorlopen)?

Het hele spul wordt geïmplementeerd op een pic32mx om menustructuren en displaydata van een SD kaart in te laden en daarmee oa het scherm aan te sturen. Daarom zijn alle formaten ook onbekend. Alles staat gedefinieerd op de SD kaart.

Ik moet alleen het vrijmaken van het geheugen nog fixen. Ergens blijft nu nog geheugen gealloceerd vermoed ik. Bij de 4e inlaadronde stopt hij er nu mee. (hij doet nu steeds: inladen-->op scherm zetten-->verwijderen uit geheugen --> inladen.....).

In de struct zit wel een aparte character pointer naar een string van onbekende lengte, maar die free ik apart zoals het vziw moet. dus:
free(struct->pointer)
free(struct)
De normale velden hoeven niet apart las ik (chars enzo)
Pagina: 1