[C] dynamisch array in functie aanmaken

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Michael
  • Registratie: Maart 2000
  • Laatst online: 01-07 14:46
Weet niet precies hoe ik mijn probleem moet omschrijven, maar ik probeer dus een array aan te maken op de plek van een pointer die als argument word meegegeven aan de functie.

Aangezien de code meer zegt dan ik kan uitleggen hier de code:

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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef struct foo_s {
    char *bar;
} foo;
 
 
int main(int argc, char **argv)
{
    foo *array;
    int num_elements;
    int i;
    num_elements = create_array(&array);
 
    for (i =0; i< num_elements; i++)
    {
        printf("%s\n", array[i].bar);
    }
 
}
 
 
int create_array(foo **out)
{
    int elements = 10;
    *out = malloc(sizeof(foo *) * elements);
 
    for (int i = 0; i < elements; i++)
    {
        out[i] = malloc(sizeof(foo));
        out[i]->bar = strdup("some data");
    }
 
    return elements;   
}


Echter werkt dat helaas niet echt:

% ./a.out
some data
(null)
(null)
(null)
Segmentation fault


Iemand een idee wat ik fout doe?

Acties:
  • 0 Henk 'm!

  • KopjeThee
  • Registratie: Maart 2005
  • Niet online
Moet het niet zijn:
C:
1
2
3
4
5
6
7
8
9
10
11
12
int create_array(foo **out)
{
    int elements = 10;
    *out = malloc(sizeof(foo) * elements);
 
    for (int i = 0; i < elements; i++)
    {
        (*out)[i].bar = strdup("some data");
    }
 
    return elements;   
}

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

KopjeThee heeft het bij het rechte eind. array in main() is een foo*, geen foo** - oftewel, elk element in de array is een foo en geen foo*.

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.


Acties:
  • 0 Henk 'm!

  • Michael
  • Registratie: Maart 2000
  • Laatst online: 01-07 14:46
Ah daar had ik nog aan gedacht. Mijn eerste idee was eigenlijk inderdaad het maken van een array van pointers naar struct foo. Hoewel dit uiteraard ook prima werkt ben ik eigenlijk wel benieuwd naar hoe ik dat voor elkaar krijg dan.

Thnx iedergeval!

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Nou dat lijkt me vrij logisch. Wat is een array van pointers naar foo? En wat zal de pointer naar zo'n variabele dan zijn?

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.


Acties:
  • 0 Henk 'm!

  • Michael
  • Registratie: Maart 2000
  • Laatst online: 01-07 14:46
hm ok :-)

foo **array; in main() en dan onderstaande lijkt te werken.

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
int create_array(foo ***out)
{
    int elements = 10;
    *out = malloc(sizeof(foo *) * elements);
    
    for (int i = 0; i < elements; i++)
    {
        (*out)[i] = malloc(sizeof(foo));
        (*out)[i]->bar = strdup("some data");
    }
    
    return elements;   
}

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

chapeau d:)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.


Acties:
  • 0 Henk 'm!

  • sam.vimes
  • Registratie: Januari 2007
  • Laatst online: 08-06 08:44
Tip voor de volgende keer: zet eerst je warning level op maximaal en werk alle warnings weg. Dat scheelt vaak al een hoop potentiële fouten.
$ g++ -Wall foobar.cpp
foobar.cpp: In function `int main(int, char**)':
foobar.cpp:15: error: `create_array' undeclared (first use this function)
foobar.cpp:15: error: (Each undeclared identifier is reported only once for each function it appears in.)
foobar.cpp: In function `int create_array(foo**)':
foobar.cpp:26: error: `int create_array(foo**)' used prior to declaration
foobar.cpp:28: error: invalid conversion from `void*' to `foo*'
foobar.cpp:32: error: invalid conversion from `void*' to `foo*'

Vooral de warning bij regel 32 zou je op het spoor van de oplossing hebben gezet.

Noot: De reden dat ik g++ heb gebruikt in plaats van gcc is dat jouw programma geen geldig C bevat:
C:
1
for (int i = 0; i < elements; i++)

bevat een C++ constructie.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11:51
sam.vimes schreef op donderdag 08 november 2007 @ 09:59:
Noot: De reden dat ik g++ heb gebruikt in plaats van gcc is dat jouw programma geen geldig C bevat:
C:
1
for (int i = 0; i < elements; i++)

bevat een C++ constructie.
Nee dat is C99

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.


Acties:
  • 0 Henk 'm!

  • Michael
  • Registratie: Maart 2000
  • Laatst online: 01-07 14:46
sam.vimes schreef op donderdag 08 november 2007 @ 09:59:
Tip voor de volgende keer: zet eerst je warning level op maximaal en werk alle warnings weg. Dat scheelt vaak al een hoop potentiële fouten.
Ik compile me code altijd met

gcc -ansi -std=c99 -g3 -ggdb  -Wall -Winline 


Volgens mij is dat de meest juiste manier om standaard ansi c te krijgen?

Iedergeval in de echte code heb ik overigens die int i = 0; inderdaad netjes aan het begin van de functie staan.

http://libnzbfetch.googlecode.com/svn/

Acties:
  • 0 Henk 'm!

  • phobosdeimos
  • Registratie: Augustus 2007
  • Laatst online: 14:30
Euh nee, ansi C is gewoon ansi C.
C99 is veel geavanceerder dan ansi C.
Als je echt puur ansi C wilt, dan mag je geen // comments gebruiken, mag je die for loop init niet gebruiken, moet je alle variabelen bovenaan declareren, en dergelijke.
Ansi C is echt de "oer C" vorm (tenzij je pure K&R C meetelt natuurlijk :D)

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11:51
Michael schreef op donderdag 08 november 2007 @ 10:49:
gcc -ansi -std=c99 -g3 -ggdb  -Wall -Winline 
-ansi en -std=99 spreken elkaar tegen ... -ansi slaat op de C89 versie en -c99 op de C99 versie

[edit]
Ik zie nu dat -std=C90 hetzelfde is als -ansi

[ Voor 10% gewijzigd door farlane op 08-11-2007 13:20 ]

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.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

phobosdeimos schreef op donderdag 08 november 2007 @ 11:35:
Euh nee, ansi C is gewoon ansi C.
C99 is veel geavanceerder dan ansi C.
Als je echt puur ansi C wilt, dan mag je geen // comments gebruiken, mag je die for loop init niet gebruiken, moet je alle variabelen bovenaan declareren, en dergelijke.
Ansi C is echt de "oer C" vorm (tenzij je pure K&R C meetelt natuurlijk :D)
Bliep, C90 en C99 zijn beide ISO en ANSI standaarden (hoewel bij ANSI de eerste C89 heet, omdat ISO dat later pas heeft overgenomen). Dat gcc niet helemaal correct is met de naamgeving van z'n compileropties of dat de mensen meestal C89 bedoelen als ze ANSI C zeggen doet daar helemaal niets aan af.

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.

Pagina: 1