Obliczanie wielkosci typow przez "sizeof"

Wyświetlono archiwalną wersję tematu "Obliczanie wielkosci typow przez "sizeof"" z forum pl.comp.programming

Milo - 12 Paź 1999, 03:00

Czy sizeof podaje dobra wielkosc typu?
Zauwazylem ze nie bardzo. Oto przyklad(BCB 3).

tworze strukture:

struct A{
__int16 x;
long y;

};


potem objekt

A t;

i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
jak mu dam takie wyrazenie sizeof(__in16)+sizeof(long) to wratosc jest....6!!
Moze mi ktos rozwiklac ta zagadke??

Maciej Walaszek - 12 Paź 1999, 03:00


Czy sizeof podaje dobra wielkosc typu?
Zauwazylem ze nie bardzo. Oto przyklad(BCB 3).

tworze strukture:

struct A{
__int16 x;
long y;
};

potem objekt

A t;

i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
jak mu dam takie wyrazenie sizeof(__in16)+sizeof(long) to wratosc
jest....6!!
Moze mi ktos rozwiklac ta zagadke??


Kompilator 'pakuje' struktury dopełniając do zadanej wielokrotności
(szybszy dostep przez procesor), pewnie masz standardowo ustawione na 4.Po
prostu pomiędzy x a y jest dwa bajty puste.

np.w watcomie jest dyrektywa
#pragma pack(nn)
nn - żądana wielokrotność (np 1 i wszystko jest tak jak sobie policzysz)

patka - 12 Paź 1999, 03:00


Czy sizeof podaje dobra wielkosc typu?
Zauwazylem ze nie bardzo. Oto przyklad(BCB 3).
tworze strukture:
struct A{
__int16 x;
long y;
};
potem objekt
A t;
i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
jak mu dam takie wyrazenie sizeof(__in16)+sizeof(long) to wratosc jest....6!!
Moze mi ktos rozwiklac ta zagadke??


Struktura nie musi miec dokladnie rozmiaru sumy swoich skladowych,
dochodzi czesto cos takiego jak wyrownanie - dorzucane sa dodatkowe
bajty aby odpowiednio ustawic adresy (rozmiary) skladowych (w tym
przypadku
nastepuje wyrownanie do 4 bajt-ow - magiczne 32 bity:). Dane zajmuja
wtedy troche wiecej miejsca, ale dostep do nich jest szybszy.

hej
patka

P.S. Powinna istniec opcja kompilatora, ktora wylacza wyrownywanie.

Pedro - 12 Paź 1999, 03:00


Czy sizeof podaje dobra wielkosc typu?
Zauwazylem ze nie bardzo. Oto przyklad(BCB 3).

tworze strukture:

struct A{
__int16 x;
long y;
};

potem objekt

A t;

i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
jak mu dam takie wyrazenie sizeof(__in16)+sizeof(long) to wratosc jest....6!!
Moze mi ktos rozwiklac ta zagadke??


Problem w tym ze w zaleznosci od realizacji jezyka programowania nastepuje
wyrownania pol w strukturze w tym przypadku typ int16 jest wyrowyway do wiekszego
typu long dlatego wynik 8 a nie 6
--
Milo

ICQ: 14939954


Milo - 12 Paź 1999, 03:00



| Czy sizeof podaje dobra wielkosc typu?
| Zauwazylem ze nie bardzo. Oto przyklad(BCB 3).
| tworze strukture:
| struct A{
| __int16 x;
| long y;
| };
| potem objekt
| A t;
| i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
| jak mu dam takie wyrazenie sizeof(__in16)+sizeof(long) to wratosc
jest....6!!
| Moze mi ktos rozwiklac ta zagadke??

Struktura nie musi miec dokladnie rozmiaru sumy swoich skladowych,
dochodzi czesto cos takiego jak wyrownanie - dorzucane sa dodatkowe
bajty aby odpowiednio ustawic adresy (rozmiary) skladowych (w tym
przypadku
nastepuje wyrownanie do 4 bajt-ow - magiczne 32 bity:). Dane zajmuja
wtedy troche wiecej miejsca, ale dostep do nich jest szybszy.
P.S. Powinna istniec opcja kompilatora, ktora wylacza wyrownywanie.


Istnieje "Data aligment" i mam ja standardowo ustawiona na "Double Word",
czyli 4 bajty, ale jest jeden problem. Gdy zmieniam ja na np. Word i
wszystkow przekompiluje, to dostaje bledy typu "Acces violination at addess
......" w bibliotece vcl35.bpl. Czy mozna cos z tym zrobic?
Rozmiar struktury jest mi potzrebny do odczytu z pliku.

patka - 12 Paź 1999, 03:00


| Struktura nie musi miec dokladnie rozmiaru sumy swoich skladowych,
| dochodzi czesto cos takiego jak wyrownanie - dorzucane sa dodatkowe
| bajty aby odpowiednio ustawic adresy (rozmiary) skladowych (w tym
| przypadku
| nastepuje wyrownanie do 4 bajt-ow - magiczne 32 bity:). Dane zajmuja
| wtedy troche wiecej miejsca, ale dostep do nich jest szybszy.
| P.S. Powinna istniec opcja kompilatora, ktora wylacza wyrownywanie.
Istnieje "Data aligment" i mam ja standardowo ustawiona na "Double Word",
czyli 4 bajty, ale jest jeden problem. Gdy zmieniam ja na np. Word i
wszystkow przekompiluje, to dostaje bledy typu "Acces violination at addess
......" w bibliotece vcl35.bpl. Czy mozna cos z tym zrobic?


Z tym to chyba nic :(

Rozmiar struktury jest mi potzrebny do odczytu z pliku.


To w czym przeszka Ci wyrownywanie do 4-bajtow? (Moze jakis kod).
Zmienia Ci sie rozmiar struktury, ale sizeof zwraca rzeczywisty wynik,
wiec z zapisem i odczytem (bajtowym calej struktury) nie powinno byc
problemu, a tym bardziej, jezeli zapisujesz kazda skladowa osobno.

pozdrowienia
patka

Serek - 12 Paź 1999, 03:00


Czy sizeof podaje dobra wielkosc typu?
Zauwazylem ze nie bardzo. Oto przyklad(BCB 3).

tworze strukture:

struct A{
__int16 x;
long y;
};

potem objekt

A t;

i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
jak mu dam takie wyrazenie sizeof(__in16)+sizeof(long) to wratosc
jest....6!!
Moze mi ktos rozwiklac ta zagadke??

--
Milo

ICQ: 14939954


Caly problem w tym, ze kompilatory 32 bitowe "lubia"
wyrownywac rekordy do wielokrotnosci 32 bitow ;)))))
Ale nie przejmuj sie w opcjach projektu wylacz cos takiego:
"Aligned record fields"
i wtedy okze sie ze podana struktura ma odpowiednia dlugosc.

Z pozdrowieniem Jacek Korzewski

Maciej Walaszek - 12 Paź 1999, 03:00




| Czy sizeof podaje dobra wielkosc typu?
| Zauwazylem ze nie bardzo. Oto przyklad(BCB 3).
| tworze strukture:
| struct A{
| __int16 x;
| long y;
| };
| potem objekt
| A t;
| i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
| jak mu dam takie wyrazenie sizeof(__in16)+sizeof(long) to wratosc
jest....6!!
| Moze mi ktos rozwiklac ta zagadke??

| Struktura nie musi miec dokladnie rozmiaru sumy swoich skladowych,
| dochodzi czesto cos takiego jak wyrownanie - dorzucane sa dodatkowe
| bajty aby odpowiednio ustawic adresy (rozmiary) skladowych (w tym
| przypadku
| nastepuje wyrownanie do 4 bajt-ow - magiczne 32 bity:). Dane zajmuja
| wtedy troche wiecej miejsca, ale dostep do nich jest szybszy.
| P.S. Powinna istniec opcja kompilatora, ktora wylacza wyrownywanie.
Istnieje "Data aligment" i mam ja standardowo ustawiona na "Double Word",
czyli 4 bajty, ale jest jeden problem. Gdy zmieniam ja na np. Word i
wszystkow przekompiluje, to dostaje bledy typu "Acces violination at
addess
......" w bibliotece vcl35.bpl. Czy mozna cos z tym zrobic?
Rozmiar struktury jest mi potzrebny do odczytu z pliku.


spróbuj coś takiego (u mnie to działa, też czytam z pliku)

#pragma pack(push, 1)
  definicja struktury
#pragma pack (pop)

aha, to jest Watcom 11, ale może w innych tez działa

Marcin 'Qrczak' Kowalczyk - 12 Paź 1999, 03:00


[...]

i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!


[...]

Prawie wszyscy dali radę, żeby przełączyć opcję jakiegoś kompilatora,
coby pakował struktury ciaśniej.

Tymczasem moja rada: nic takiego nie robić, nie przejmować się,
tak ma być. Język C ani C++ nie gwarantuje konkretnego rozłożenia
elementów struktur i już.

I tak nie uzyskamy np. przenośności przez pakowanie struktur: po
pierwsze opcja pakowania, o ile w ogóle istnieje, jest prywatnym
rozszerzeniem konkretnego kompilatora, po drugie wielkości typów
całkowitych w różnych kompilatorach są różne, o jeszcze większych
różnicach między architekturami (endianness) nie wspominając.

Kompilatory dają "puste" miejsca w strukturach nie bez powodu, nie
należy ich poprawiać, chyba że wiemy co robimy.

Milo - 12 Paź 1999, 03:00

spróbuj coś takiego (u mnie to działa, też czytam z pliku)

#pragma pack(push, 1)
  definicja struktury
#pragma pack (pop)


Dziala!!! To dziala!!! :)))
Dzieki stokrotne. Jestem uratowany.:))
A co do tresci to juz sobie reszte z helpow doczytalem co do czego sluzy. Ten
drugi parametr jest wielkoscia do jakiej beda wyrownywane struktury(moze byc
1, 2, 4, 8 i 16 bajtow jak sadze, choc moze i bitow; tego nie doczytalem).
O co do opcji kompilatora to nie znalazlem takiej dotyczacej wyrownywania
struktur, wiec jestem "skazany" na dyrektywy. Ale robie sobie to tak, ze push
na poczatku wszystkich struktur, potem struktury a potem pop i to dziala.
Dzieki raz jeszcze.

Milo - 12 Paź 1999, 03:00

To w czym przeszka Ci wyrownywanie do 4-bajtow? (Moze jakis kod).
Zmienia Ci sie rozmiar struktury, ale sizeof zwraca rzeczywisty wynik,
wiec z zapisem i odczytem (bajtowym calej struktury) nie powinno byc
problemu, a tym bardziej, jezeli zapisujesz kazda skladowa osobno.


No dobra, ale te dane sa juz zapisane wczesniej bez wyrownania do 4
bajtow(wiec int ma 2 a nie 4 bajty). Moglbym co prawda odczytywac kazde pole
osobno, ale po co sie bawic, skoro mozna to zrobic od razu?

Milo - 12 Paź 1999, 03:00

Caly problem w tym, ze kompilatory 32 bitowe "lubia"
wyrownywac rekordy do wielokrotnosci 32 bitow ;)))))
Ale nie przejmuj sie w opcjach projektu wylacz cos takiego:
"Aligned record fields"
i wtedy okze sie ze podana struktura ma odpowiednia dlugosc.


Takiego czegos, nie mam, ale problem juz rozwiazalem.

Milo - 12 Paź 1999, 03:00



[...]
| i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
[...]

Prawie wszyscy dali radę, żeby przełączyć opcję jakiegoś kompilatora,
coby pakował struktury ciaśniej.

Tymczasem moja rada: nic takiego nie robić, nie przejmować się,
tak ma być. Język C ani C++ nie gwarantuje konkretnego rozłożenia
elementów struktur i już.

I tak nie uzyskamy np. przenośności przez pakowanie struktur: po
pierwsze opcja pakowania, o ile w ogóle istnieje, jest prywatnym
rozszerzeniem konkretnego kompilatora, po drugie wielkości typów
całkowitych w różnych kompilatorach są różne, o jeszcze większych
różnicach między architekturami (endianness) nie wspominając.

Kompilatory dają "puste" miejsca w strukturach nie bez powodu, nie
należy ich poprawiać, chyba że wiemy co robimy.


Mi to bylo bardzo potrzebne(przenosilem program z 16 bit na 32bit, wiec
zmienil sie rozmiar sytruktur i tym samym sposob ich odczytu z dysku co jest
nieporzadane). Musialem poza tym uzyc typu __int16 zamiast int, bo ten drugi
okazuje sie, ze ma wielkosc 4 bajtow, czyli tyle co long(ciekawa jaki jest
teraz sens uzywania int'a).

Tomasz Szpakowicz - 13 Paź 1999, 03:00


Istnieje "Data aligment" i mam ja standardowo ustawiona na "Double Word",
czyli 4 bajty, ale jest jeden problem. Gdy zmieniam ja na np. Word i
wszystkow przekompiluje, to dostaje bledy typu "Acces violination at addess
......" w bibliotece vcl35.bpl. Czy mozna cos z tym zrobic?
Rozmiar struktury jest mi potzrebny do odczytu z pliku.


Upewnij sie, ze we wszystkie jednostki translacji
kompilujesz z ta opcja (aby wlaczane tam struktury mialy ten sam
uklad w pamieci).

Problem pojawia sie, gdy masz struktury, ktore sluza do komunikacji
z zewnetrznymi bibliotekami. Tych nie mozesz 'poprawiac'.

Czesto nie mozna, wiec tak po prostu zmieniac globalnej opcji.
Pozostaja pragmy, byc moze:

#pragma push
#pragma pack(1)

  ... tu struktura, ktora musi byc wyrownywana do jednego bajtu ...

#pragma pop

czy jakos tak.

Paweł Ziemian - 13 Paź 1999, 03:00



do grup

| [...]
| i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
| [...]

| Prawie wszyscy dali radę, żeby przełączyć opcję jakiegoś kompilatora,
| coby pakował struktury ciaśniej.

| Tymczasem moja rada: nic takiego nie robić, nie przejmować się,
| tak ma być. Język C ani C++ nie gwarantuje konkretnego rozłożenia
| elementów struktur i już.

| I tak nie uzyskamy np. przenośności przez pakowanie struktur: po
| pierwsze opcja pakowania, o ile w ogóle istnieje, jest prywatnym
| rozszerzeniem konkretnego kompilatora, po drugie wielkości typów
| całkowitych w różnych kompilatorach są różne, o jeszcze większych
| różnicach między architekturami (endianness) nie wspominając.

| Kompilatory dają "puste" miejsca w strukturach nie bez powodu, nie
| należy ich poprawiać, chyba że wiemy co robimy.
Mi to bylo bardzo potrzebne(przenosilem program z 16 bit na 32bit, wiec
zmienil sie rozmiar sytruktur i tym samym sposob ich odczytu z dysku co
jest
nieporzadane). Musialem poza tym uzyc typu __int16 zamiast int, bo ten
drugi
okazuje sie, ze ma wielkosc 4 bajtow, czyli tyle co long(ciekawa jaki
jest
teraz sens uzywania int'a).


Moim zdaniem w takim przypadku powinno się zrobić rekord dyskowy, który
jest tylko tablicą bajtów. Rekord ten będzie wypełniany i odczytywany
specjalnymi procedurkami, co zapewni nam przenaszalność na wszystkie
kompilatory i platformy (no prawie, zakładając, że wiemy co robimy, że
bajt jest bajt itd).

struct moja_struktura
{
  int  pole1;
  long pole2;

};


struct dane_plikowe
{
  unsigned char dane[ROZMIAR_DANYCH];

};


oraz dopisać sobie funkcyjki:

void zrob_dane_plikowe ( moja_struktura * z, dane_plikowe * do )
{
  do-dane[0] = z-pole1 % 256;
  do-dane[1] = z-pole1 / 256;
  do-dane[2] = z-pole2 % 256;
  do-dane[3] = z-pole2 / 256;
  do-dane[4] = z-pole2 / 65536;
  do-dane[5] = z-pole2 / (65536*256);

}


void zrob_moja_strukture ( dane_plikowe * z, moja_struktura * do )
{
  pole1 = 256 * z-dane[1]
        +       z-dane[0];
  pole2 = (256*65536) * z-dane[5]
        +       65536 * z-dane[4]
        +         256 * z-dane[3]
        +               z-dane[2];

}


Gdy wiec program zostanie przeniesiony na inna platforme i się nam
wszystko poprzesuwa w strukturze wewnetrznej programu to dzieki
"ręcznemu" pakowaniu i rozpakowywaniu struktura pliku pozostaje bez
zmian. Ponadto w rekordzie plikowym nie ma "dziur", co mogło by
powodować zapisywanie niepotrzebnych "śmieci" utrudniające np.
kompresowanie danych podczas ich archiwizowania.

Marcin 'Qrczak' Kowalczyk - 14 Paź 1999, 03:00


Musialem poza tym uzyc typu __int16 zamiast int, bo ten drugi okazuje
sie, ze ma wielkosc 4 bajtow, czyli tyle co long (ciekawa jaki jest
teraz sens uzywania int'a).


Taki sam jak wtedy, kiedy int ma 16 bitów, tyle co short :-)

Jeśli nie ma powodu, żeby używać innego typu całkowitego, używa się
inta. int z założenia jest naturalnej wielkości dla danego środowiska.
Jeśli kompilator wykorzystuje 32bitowe rejestry, to int będzie pewnie
32bitowy. A jeśli procesor może liczyć na 64 bitach, to long może
mieć 64 bity...

Poszukuje narzedzi do obliczania wartosci wlasnych i wektorow wlasnych
Czy telewizory, monitory testowane codziennie przez caly rok w supermarketach traca emisje ?
Procedura obliczajaca liczbe dni pomiedzy dwoma datami
połaczeni kliku komputerów (serwerów) i wykorzystanie ich mocy do obliczeń
Rzad zlozonosci obliczeniowej: symbole O, Teta, Omega
Problem algorytmiczny
OCaml
  • idz do podstrony 120
  • znajdz kaleba
  • dominik uram
  • szczecin fajna psia impreza 30 sierpnia 12 oo
  • anna glimos nadgorska
  • 2222joanna goszcz2222
  • miejskim w bydgoszczy
  • karty prepaid
  • pawel z tarsu
  • cracy Frog lider
  • ojciec rydzyka
  • shoarma kuchnia
  • Zbieranina tematów z for dyskusyjnych || Index