/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
minus én plus ti
Fra : Troels Thomsen


Dato : 15-03-04 16:23

Er flg en almindelig konstruktion ?

typedef struct
{
char a;
char data[1];
} S1;


typedef struct
{
char b;
S1 s1obj;
} S2;


void f1(unsigned char dataLength )
{
char i;

S2* ps2 = malloc((sizeof(S2)-1) + dataLength);

for (i = 0 ; i < dataLength ; ++i)
{
ps2->s1obj.data[i] = i; // fill in some data
}

anotherFunc (ps2); // somebody uses this struct and data
}

Jeg synes det er lidt fusket at allokere ét element og så malloce et større
område så det kommer til at passe.

Det er vel _garanteret_ at S1::data ligger til allersidst i S2 structet, så
det _altid_ går godt, eller?

Alternativet var jo bare at 'data' var char pointer. Så laver man structet,
allokerer en char buffer med malloc, assigner pointeren til S1::data.

Det er noget kode der skal køre i en microcontroller. Måske bliver der et
par instruktioner mindre ud af denne måde at gøre det på? Jeg prøver sådan
set bare at forstå hvorfor de har gjort som de har !

mvh Troels




 
 
Bertel Brander (15-03-2004)
Kommentar
Fra : Bertel Brander


Dato : 15-03-04 19:14

Troels Thomsen wrote:

> Det er vel _garanteret_ at S1::data ligger til allersidst i S2 structet, så
> det _altid_ går godt, eller?

For C (jeg kender ikke nok til C++ til at vide om det er lovligt der):
http://www.eskimo.com/~scs/C-faq/q2.6.html

>
> Alternativet var jo bare at 'data' var char pointer. Så laver man structet,
> allokerer en char buffer med malloc, assigner pointeren til S1::data.

I så fald skal man allokere to gange, en gang for struct'en og
en gang for pointeren.

/b


Bertel Brander (15-03-2004)
Kommentar
Fra : Bertel Brander


Dato : 15-03-04 19:38

Bertel Brander wrote:

> Troels Thomsen wrote:
>
>> Det er vel _garanteret_ at S1::data ligger til allersidst i S2
>> structet, så
>> det _altid_ går godt, eller?
>
>
> For C (jeg kender ikke nok til C++ til at vide om det er lovligt der):
> http://www.eskimo.com/~scs/C-faq/q2.6.html
>

Ved nærmere eftertanke;

I C99 (og nogle pre-C99 kompilere) kan man bruge:

struct s
{
int n;
double d[];
};

Så behøver man ikke at trække én fra. I C99 er
det garanteret at hacket virker.

Bemærk også at minus en ikke altid giver den rigtige
størrelse (pga. padding), man kan bruge offsetof()
til at finde den nøjagtige størrelse, hvis det er
vigtigt.

/b


Troels Thomsen (17-03-2004)
Kommentar
Fra : Troels Thomsen


Dato : 17-03-04 09:33

>
> struct s
> {
> int n;
> double d[];
> };
>

C99, Ok, det vil lige denne Metrowerks HCS08 compiler så ikke.
Begge de to IAR compilere (den ene fra 1998) vil godt.


> Bemærk også at minus en ikke altid giver den rigtige
> størrelse (pga. padding), man kan bruge offsetof()
> til at finde den nøjagtige størrelse, hvis det er
> vigtigt.
>

Mener du (sizeof(s1) - offsetof(data))?
Men som du skriver er det ofte lige meget, at man får et par bytes for meget
allokeret.

mvh tpt




Bertel Brander (17-03-2004)
Kommentar
Fra : Bertel Brander


Dato : 17-03-04 17:32

Troels Thomsen wrote:

>>Bemærk også at minus en ikke altid giver den rigtige
>>størrelse (pga. padding), man kan bruge offsetof()
>>til at finde den nøjagtige størrelse, hvis det er
>>vigtigt.
>>
>
>
> Mener du (sizeof(s1) - offsetof(data))?

Jeg mener offsetof(struct s, a), f.ex:

#include <stdio.h>

struct s
{
int i;
char a[1];
};

int main(void)
{
printf("Sizeof: %d Offsetof: %d\n", sizeof(Struct) - 1,
offsetof(Struct, a));
return 0;
}

Med en tilfældig kompiler får jeg hhv 7 og 4, hvilket måske
ikke er atypisk.

/b


Frederik Hertzum (22-03-2004)
Kommentar
Fra : Frederik Hertzum


Dato : 22-03-04 20:10

Bertel Brander wrote:

> Bertel Brander wrote:
>
>> Troels Thomsen wrote:
>>
>>> Det er vel _garanteret_ at S1::data ligger til allersidst i S2
>>> structet, så
>>> det _altid_ går godt, eller?
>>
>>
>> For C (jeg kender ikke nok til C++ til at vide om det er lovligt der):
>> http://www.eskimo.com/~scs/C-faq/q2.6.html
>>
>
> Ved nærmere eftertanke;
>
> I C99 (og nogle pre-C99 kompilere) kan man bruge:
>
> struct s
> {
> int n;
> double d[];
> };
>
> Så behøver man ikke at trække én fra. I C99 er
> det garanteret at hacket virker.
>

Et alternativ ville være

struct s
{

int n;
double * d;
}

void function(int size) // find size på en eller anden måde
{
s * a;
a = malloc(size);
a->d = function_to_find_d(a);
}

Jeg kender ikke C godt nok til at skrive resten af programmet, men det her
skulle gøre det samme og samtidig sikre at det kan compile på GCC compilere
(i hvert fald).


Niels Dybdahl (15-03-2004)
Kommentar
Fra : Niels Dybdahl


Dato : 15-03-04 22:11

> Det er noget kode der skal køre i en microcontroller. Måske bliver der et
> par instruktioner mindre ud af denne måde at gøre det på? Jeg prøver sådan
> set bare at forstå hvorfor de har gjort som de har !

I en microcontroller kan der være hardware der forventer at det ligger ud i
en køre. I så fald er det en ret almindelig skrivemåde. Der er vist også
nogen strukturer i Windows API (BITMAPHEADER) som er defineret på lignende
måde. Der er pointen ssv at holde samme struktur i RAM som i en fil.

Niels Dybdahl



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408921
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste