|
| pointere Fra : Peter Jensen |
Dato : 30-11-02 22:44 |
|
Hej
Jeg har 2 void pointere til hver sin blok hukommelse. Hvis jeg har en tredje
pointer jeg ved peger i en af de to blokke, hvordan kan jeg så tjekke
hvilken??
På forhånd tak
\Peter
| |
Morten F. Hansen (30-11-2002)
| Kommentar Fra : Morten F. Hansen |
Dato : 30-11-02 23:00 |
|
> Jeg har 2 void pointere til hver sin blok hukommelse. Hvis jeg har en tredje
> pointer jeg ved peger i en af de to blokke, hvordan kan jeg så tjekke
> hvilken??
Hvad med at caste dem til int eller long eller hvad der nu passer, og så teste
hvilken af de to første den tredie ligger tættest på?
| |
Mogens Hansen (01-12-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 01-12-02 14:15 |
|
"Morten F. Hansen" <info@127.0.0.1> wrote in message
news:asbceo$9ks$1@sunsite.dk...
> Hvad med at caste dem til int eller long eller hvad der nu passer, og så
teste
> hvilken af de to første den tredie ligger tættest på?
Hvilken garanti har du for at man kan caste void* til int eller long og få
noget som helst brugbart ud af det ?
Tænk f.eks. på hvad der sker på Intel's segmenterede 16-bit x86 arkitektur.
Man har en garanti for at man kan caste en hvilken som helst type pointer
til "void*" og tilbage og få den oprindelige peger igen.
Man har garanti for at man med "memcpy" kan kopiere en pointer til et
tilstrækkeligt stort char[] , og tilbage igen og få den oprindelige peger
igen.
Hvorfor skal man caste dem til int eller long, i stedet for blot at behandle
dem som pointere ?
<ikke compileret kode>
template <typename T>
inline bool points_to_block(const T* block_begin, const T* block_end, const
T* p)
{
return block_begin <= p && block_end >= p ? true : false;
}
template <typename T>
inline bool points_to_block(const T* block_begin, size_t block_length, const
T* p)
{
return points_to_block(block_begin, block_begin + block_length, p);
}
</ikke compileret kode>
Bemærk t det ikke er _garanteret_ at ovenstående vil virke (§5.9-10), men
jeg har svært ved at forstille mig en situation hvor det ikke vil være
tilfældet.
En _garanteret_ korrekt (§5.10-2), men langt mindre effektiv, test vil være
<ikke compileret kode>
template <typename T>
bool points_to_block(const T* block_begin, const T* block_end, const T* p)
{
while(block_begin != block_end && block_begin != p)
++block_begin;
return block_begin != block_end;
}
</ikke compileret kode>
Venlig hilsen
Mogens Hansen
| |
Byrial Jensen (01-12-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 01-12-02 21:15 |
|
Mogens Hansen <mogens_h@dk-online.dk> skrev:
>
> Man har en garanti for at man kan caste en hvilken som helst type pointer
> til "void*" og tilbage og få den oprindelige peger igen.
> Man har garanti for at man med "memcpy" kan kopiere en pointer til et
> tilstrækkeligt stort char[] , og tilbage igen og få den oprindelige peger
> igen.
Du snakker formodentlig om C++.
I C har man ikke garanti for at en vilkårlig pointer kan konverteres
til "void *" og tilbage igen. Det gælder for pointere til objekter,
men ikke for pointere til funktioner. Der er til gengæld garanti for
at en pointer til en type funktion kan konverteres til en pointer
til en anden type funktion og tilbage igen.
I C har man også garanti for at en vilkårlig pointer til et object
kan konverteres til en "char *" som peger på den lavest adresserede
byte i objektet. Pointeren kan også inkrementeres til at pege på de
efterfølgende bytes så længe man ikke overskrider objektets
størrelse (størrelsen måles med sizeof-operatoren).
Hvad du i øvrigt skriver gælder også for C (bortset fra at der ikke
findes templates i C).
--
Skal musik- og edb-industrien have ret til fratage forbrugerne deres
rettigheder i henhold til Ophavsretloven, begrænse konkurrencen og
fremme monopoldannelse ved hjælp af tekniske midler? Sig nej! Nu!
Støt underskriftsindsamlingen på http://www.digitalforbruger.dk
| |
Mogens Hansen (01-12-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 01-12-02 22:18 |
|
"Byrial Jensen" <bjensen@nospam.dk> wrote in message
news:slrnaukr9t.15t.bjensen@ask.ask...
[8<8<8<]
> Du snakker formodentlig om C++.
ja, det var meninngen - men det var præcist nok
>
> I C har man ikke garanti for at en vilkårlig pointer kan konverteres
> til "void *" og tilbage igen. Det gælder for pointere til objekter,
> men ikke for pointere til funktioner.
Jeg var upræcis - tak.
Det er det samme, der gælder i C++.
Venlig hilsen
Mogens Hansen
| |
Bertel Lund Hansen (30-11-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 30-11-02 23:16 |
|
Peter Jensen skrev:
>Jeg har 2 void pointere til hver sin blok hukommelse. Hvis jeg har en tredje
>pointer jeg ved peger i en af de to blokke, hvordan kan jeg så tjekke
>hvilken?
Det lyder ret obskurt, men du kan behandle pointerens pegeadresse
som en int og teste på om den ligger i et givet interval.
// Leger at blokkene er på 100 enheder.
void *p, *q, *r;
...
if (q>=p && q<p+100) printf("q peger i p's blok.");
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Mogens Hansen (01-12-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 01-12-02 14:12 |
|
"Bertel Lund Hansen" <nospam@lundhansen.dk> wrote in message
news:c0eiuu8oivjndr9v18h7n9beo1kld02a1c@news.stofanet.dk...
[8<8<8<]
> Det lyder ret obskurt, men du kan behandle pointerens pegeadresse
> som en int og teste på om den ligger i et givet interval.
>
> // Leger at blokkene er på 100 enheder.
> void *p, *q, *r;
> ...
>
> if (q>=p && q<p+100) printf("q peger i p's blok.");
Du behandler ikke pointerens værdi som en int.
Det er ganske almindelig pointer aritmetik.
Venlig hilsen
Mogens Hansen
| |
Martin Dyring (01-12-2002)
| Kommentar Fra : Martin Dyring |
Dato : 01-12-02 21:22 |
|
"Peter Jensen" <andreasa@daimi.au.dk> wrote in message
news:3de9312c$0$6143$ba624c82@nntp02.dk.telia.net...
> Hej
>
> Jeg har 2 void pointere til hver sin blok hukommelse. Hvis jeg har en
tredje
> pointer jeg ved peger i en af de to blokke, hvordan kan jeg så tjekke
> hvilken??
Jeg har ikke helt forstået formålet med tættest-på-diskussionen da det ikke
giver noget svar på hvilke blok pointeren befinder sig i.
Hvis du kender størrelsen på hver blok er det til gengælde ligefrem at teste
om din pointer ligger i intervallet [blokstart; blokstart + størrelse].
--
Mvh,
Martin Dyring
| |
Morten F. Hansen (02-12-2002)
| Kommentar Fra : Morten F. Hansen |
Dato : 02-12-02 00:47 |
|
> Jeg har ikke helt forstået formålet med tættest-på-diskussionen da det ikke
> giver noget svar på hvilke blok pointeren befinder sig i.
Nej, det gør den ikke. Jeg tænkte mig ikke om inden jeg kom med den ganske
ubrugelige metode...
> Hvis du kender størrelsen på hver blok er det til gengælde ligefrem at teste
> om din pointer ligger i intervallet [blokstart; blokstart + størrelse].
Ja, hvis jeg havde tænkt først havde jeg skrevet dette i stedet Heh!
| |
Aksel (06-12-2002)
| Kommentar Fra : Aksel |
Dato : 06-12-02 12:56 |
|
"Peter Jensen" <andreasa@daimi.au.dk> wrote in message
news:3de9312c$0$6143$ba624c82@nntp02.dk.telia.net...
> Jeg har 2 void pointere til hver sin blok hukommelse. Hvis jeg har en
tredje
> pointer jeg ved peger i en af de to blokke, hvordan kan jeg så tjekke
> hvilken??
printf("p3 peger i blok %d",p1<p2?(p2<=p3?2:1):(p1<=p3?1:2));
--
Aksel
| |
Igor V. Rafienko (06-12-2002)
| Kommentar Fra : Igor V. Rafienko |
Dato : 06-12-02 17:59 |
|
[ aksel@nogoddamnspamformeplease.dk ]
[ ... ]
> printf("p3 peger i blok %d",p1<p2?(p2<=p3?2:1):(p1<=p3?1:2));
Og du regner med at dette vil virke fordi at...?
ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
-- pederst på irc
| |
Aksel (07-12-2002)
| Kommentar Fra : Aksel |
Dato : 07-12-02 16:49 |
|
"Igor V. Rafienko" <igorr@ifi.uio.no> wrote in message
news:xjv1y4vhynb.fsf@mira.ifi.uio.no...
> [ aksel@nogoddamnspamformeplease.dk ]
>
> [ ... ]
>
> > printf("p3 peger i blok %d",p1<p2?(p2<=p3?2:1):(p1<=p3?1:2));
>
>
> Og du regner med at dette vil virke fordi at...?
Hvis p3 peger i blok 1 så vil p3 være større end eller lige med p1.
Hvis p3 peger i blok 2 så vil p3 være større end eller lige med p2.
Hvis p3 er større end eller lig med både p1 og p2 så må man sammenligne p1
med p2 for at finde svaret.
Eller sagt på en anden måde:
printf("p3 peger i blok %d",p1<p2?(p2<=p3?2:1):(p1<=p3?1:2));
--
Aksel
| |
Igor V. Rafienko (07-12-2002)
| Kommentar Fra : Igor V. Rafienko |
Dato : 07-12-02 16:57 |
|
[ aksel@nogoddamnspamformeplease.dk ]
[ ... ]
> > Og du regner med at dette vil virke fordi at...?
>
> Hvis p3 peger i blok 1 så vil p3 være større end eller lige med p1.
> Hvis p3 peger i blok 2 så vil p3 være større end eller lige med p2.
Du forstod tydeligvis ikke spørsmålet.
Hvorfor antar du at "p < q" gir mening, når p og q _ikke_ peker på det
samme objektet i memory?
ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
-- pederst på irc
| |
Aksel (07-12-2002)
| Kommentar Fra : Aksel |
Dato : 07-12-02 17:09 |
|
"Igor V. Rafienko" <igorr@ifi.uio.no> wrote in message
news:xjvvg25zusi.fsf@mira.ifi.uio.no...
> [ aksel@nogoddamnspamformeplease.dk ]
>
> [ ... ]
>
> > > Og du regner med at dette vil virke fordi at...?
> >
> > Hvis p3 peger i blok 1 så vil p3 være større end eller lige med p1.
> > Hvis p3 peger i blok 2 så vil p3 være større end eller lige med p2.
>
>
> Du forstod tydeligvis ikke spørsmålet.
>
> Hvorfor antar du at "p < q" gir mening, når p og q _ikke_ peker på det
> samme objektet i memory?
Det er void pointere. De peger ikke på nogen objekter.
--
Aksel
| |
Igor V. Rafienko (07-12-2002)
| Kommentar Fra : Igor V. Rafienko |
Dato : 07-12-02 17:17 |
|
[ aksel@nogoddamnspamformeplease.dk ]
[ ... ]
> > Hvorfor antar du at "p < q" gir mening, når p og q _ikke_ peker på
> > det samme objektet i memory?
>
> Det er void pointere. De peger ikke på nogen objekter.
Akkurat, ja. Du har ikke tilfeldigvis flere gode råd å dele ut?
Men atter en gang (vil du ikke forstå spørsmålet?) -- _hvordan_ vet du
at sammenligning av to pekere (av vilkårlig type) med operator < er
tillatt, dersom du ikke vet at de to pekere peker på det samme
objektet i minne?
ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
-- pederst på irc
| |
Aksel (07-12-2002)
| Kommentar Fra : Aksel |
Dato : 07-12-02 17:31 |
|
"Igor V. Rafienko" <igorr@ifi.uio.no> wrote in message
news:xjvu1hpztve.fsf@mira.ifi.uio.no...
> Men atter en gang (vil du ikke forstå spørsmålet?) -- _hvordan_ vet du
> at sammenligning av to pekere (av vilkårlig type) med operator < er
> tillatt, dersom du ikke vet at de to pekere peker på det samme
> objektet i minne?
Antyder du med dit spørgsmål at det kan være "forbudt" at sammenligne to
pointere? Prøv at forklare mig hvad du mener så jeg kan forstå det ;) Der er
jo ingen fejl eller advarsler under kompilering. Kan jeg få en GPF? Hvor vil
du hen? Fortæl.
--
Aksel
| |
Igor V. Rafienko (07-12-2002)
| Kommentar Fra : Igor V. Rafienko |
Dato : 07-12-02 17:48 |
|
[ aksel@nogoddamnspamformeplease.dk ]
[ ... ]
> Antyder du med dit spørgsmål at det kan være "forbudt" at
> sammenligne to pointere?
Nei, det er ikke forbudt. Men språkdefinisjonen legger ikke noen
restriksjoner på hva en implementasjon skal/ikke skal gjøre når den
får koden din.
> Prøv at forklare mig hvad du mener så jeg kan forstå det ;)
Jamen, Mogens Hansen _har_ allerede gitt alle de nødvendige
referansene (<URL:news:asd1q4$dl2$2@news.cybercity.dk>). Hva mer vil
du ha forklart?
> Der er jo ingen fejl eller advarsler under kompilering. Kan jeg få
> en GPF? Hvor vil du hen?
Jeg kan godt tenke meg en implementasjon der svaret ikke vil gi
mening.
ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
-- pederst på irc
| |
Aksel (07-12-2002)
| Kommentar Fra : Aksel |
Dato : 07-12-02 18:07 |
|
"Igor V. Rafienko" <igorr@ifi.uio.no> wrote in message
news:xjvsmx9zsgj.fsf@mira.ifi.uio.no...
> Jeg kan godt tenke meg en implementasjon der svaret ikke vil gi
> mening.
Det kan jeg ikke.
Jeg tager den lige en gang til fra begyndelsen:
Hvis p3 peger i blok 1, så vil det være "tilladt" at sammenligne p1 og p3,
og endvidere vil p3 være større end eller lige med p1.
Hvis p3 peger i blok 2, så vil det være "tilladt" at sammenligne p2 og p3,
og endvidere vil p3 være større end eller lige med p2.
Er vi enige så langt?
Hvis p3 er større end eller lig med både p1 og p2 så må man sammenligne p1
med p2 for at finde svaret. Det er muligvis ikke "tilladt" (hvad det så
dækker over), men det skulle være en meget mystisk implementasjon, hvis p3
peger i blok 1 når p3 er større end p2 og p3 er større end p1 og p2 er
større end p1. Det er faktisk ligemeget om hukommelsen er segmenteret.
Hvis vi ikke er enige, så er jeg villig til at lade tvivlen komme min
løsning til gode indtil jeg har set et eksempel på at den ikke virker. Nu
var det jo også Peter der skulle bruge den, så det er jo ham det går ud
over. ;)
--
Aksel
| |
Aksel (07-12-2002)
| Kommentar Fra : Aksel |
Dato : 07-12-02 18:14 |
|
"Aksel" <aksel@nogoddamnspamformeplease.dk> wrote in message
news:ast9rn$qkj$1@news.cybercity.dk...
> Det er faktisk ligemeget om hukommelsen er segmenteret.
Det er faktisk nok ikke helt ligemeget. Nu er selvmord eneste udvej.
| |
Igor V. Rafienko (07-12-2002)
| Kommentar Fra : Igor V. Rafienko |
Dato : 07-12-02 18:55 |
|
[ aksel@nogoddamnspamformeplease.dk ]
[ ... ]
> Jeg tager den lige en gang til fra begyndelsen:
>
> Hvis p3 peger i blok 1, så vil det være "tilladt" at sammenligne p1 og p3,
> og endvidere vil p3 være større end eller lige med p1.
> Hvis p3 peger i blok 2, så vil det være "tilladt" at sammenligne p2 og p3,
> og endvidere vil p3 være større end eller lige med p2.
>
> Er vi enige så langt?
Nei, vi er ikke enige så langt.
La meg sitere litt det Mogens refererte til:
5.9 Relational operators
1 [ ... ] The operands shall have arithmetic, enumeration or pointer
type.
2 [ ... ] Pointers to objects or functions of the same type (after
pointer conversions) can be compared, with a result defined as
follows:
-- If two pointers p and q of the same type point to the same object
[ ... ], then p <= q and p >= q both yield true and p < q and p >
q both yield false.
-- If two pointers p and q of the same type point to different
objects that are not member of the same object [ ... ], the
results of p < q, p > q, p <= q, and p >= q are unspecified.
-- If two pointers point to nonstatic data members of the same
object, [ ... ]
-- If two pointers point to nonstatic data members of the same
object, [ ... ]
-- If two pointers point to data members of the same union object,
[ ... ]
-- Other pointer comparisons are unspecified.
Riktignok har jeg utelatt en del, men essensen er at gitt to pekere
som pekere ett eller annet sted _innen samme objekt_ i minne, kan vi
sammenligne de med < med visse forbehold. Gitt to pekere som _ikke_
peker ett eller annet sted _innen samme objekt_, kan man ikke si noe
som helst om verdien av p < q på to forskjellige implementasjoner.
Derimot, for operator== gjelder det litt enklere regler, og jeg tipper
at det var nettopp dette Mogens siktet til i
<URL:news:URL:news:asd1q4$dl2$2@news.cybercity.dk>.
> Hvis p3 er større end eller lig med både p1 og p2 så må man
> sammenligne p1 med p2 for at finde svaret. Det er muligvis ikke
> "tilladt" (hvad det så dækker over), men det skulle være en meget
> mystisk implementasjon, hvis p3 peger i blok 1 når p3 er større end
> p2 og p3 er større end p1 og p2 er større end p1. Det er faktisk
> ligemeget om hukommelsen er segmenteret.
Husk at verdien av en peker kan være langt mere enn bare en adresse i
minne (segmentert eller ej). Velger man å tolke pekerverdiene som
bitmønstre på lik linje med tall, bør man helst være sikker på hva den
eventuelle tilleggsinformasjonen lagret i en peker representerer og
hva kompilatoren gjør med den, før man bruker de relasjonelle
operatorne. Lignende tanker ble uttrykkt i "DIFFERENT ARRAY INDEXING"
tråden på comp.lang.c++ i 2000.
Av ren nysgjerrighet lurer jeg også på hvordan forskjellige
kompilatorer oppfører seg på en segmentert arkitektur (fx. i386);
spesielt lurer jeg på hva en implementasjon gjør når den skal anvende
en relasjonell operator på en (segment,offset) peker.
> Hvis vi ikke er enige, så er jeg villig til at lade tvivlen komme
> min løsning til gode indtil jeg har set et eksempel på at den ikke
> virker.
Oppfører du deg slik i arbeidssituasjoner også? "Jeg antar at det er
greit å kjøre på rødt lys, inntil jeg ender opp i en kollisjon. _Da_
vil jeg revurdere kjørestilen min." er en passende parallell.
> Nu var det jo også Peter der skulle bruge den, så det er jo ham det
> går ud over. ;)
Og spesielt _da_ er det greit å dele ut råd som "virker jo for meg"?
ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
-- pederst på irc
| |
Aksel (08-12-2002)
| Kommentar Fra : Aksel |
Dato : 08-12-02 11:22 |
|
"Igor V. Rafienko" <igorr@ifi.uio.no> wrote in message
news:xjvr8ctzpcp.fsf@mira.ifi.uio.no...
> > Nu var det jo også Peter der skulle bruge den, så det er jo ham det
> > går ud over. ;)
> Og spesielt _da_ er det greit å dele ut råd som "virker jo for meg"?
Peter, modtag min uforbeholdne undskyldning ;)
| |
Per Abrahamsen (07-12-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 07-12-02 15:37 |
|
igorr@ifi.uio.no (Igor V. Rafienko) writes:
> [ aksel@nogoddamnspamformeplease.dk ]
>
> [ ... ]
>
>> printf("p3 peger i blok %d",p1<p2?(p2<=p3?2:1):(p1<=p3?1:2));
>
>
> Og du regner med at dette vil virke fordi at...?
Han antager et fladt adresserum[1] og at p3 ligger i en af de to
blokke (implicit i opgaveformuleringen).
Er der andre antagelser der er nødvendige?
Footnotes:
[1] Hvilket ikke er garanteret af sproget, men et implicit eller
eksplicit krav i mange projekter, f.eks. GNU.
| |
Igor V. Rafienko (07-12-2002)
| Kommentar Fra : Igor V. Rafienko |
Dato : 07-12-02 15:49 |
|
[ Per Abrahamsen ]
[ om pekersammenligning ]
> Han antager et fladt adresserum[1] og at p3 ligger i en af de to
> blokke (implicit i opgaveformuleringen).
>
> Er der andre antagelser der er nødvendige?
Ja. Fx. at ingen bit i en peker brukes av runtime systemet til noe
interessant (garbage collection eller type informasjon er noen av
potensielle kandidatene). Det er faktisk tilfellet i en del C++
implementasjoner allerede med pekere til medlems{variable,funksjoner}.
Men jeg vil gjerne se et svar fra Aksel.
> Footnotes: [1] Hvilket ikke er garanteret af sproget, men et
> implicit eller eksplicit krav i mange projekter, f.eks. GNU.
Nå kjenner jeg veldig dårlig memory modellen på i386, men ser gcc
_helt_ bort fra segment registrene? En annen ting er hvordan "<=" vil
oppføre seg på i386, gitt at pekerne peker på forskjellige segmenter.
ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
-- pederst på irc
| |
Per Abrahamsen (09-12-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 09-12-02 12:55 |
|
igorr@ifi.uio.no (Igor V. Rafienko) writes:
> Ja. Fx. at ingen bit i en peker brukes av runtime systemet til noe
> interessant (garbage collection eller type informasjon er noen av
> potensielle kandidatene). Det er faktisk tilfellet i en del C++
> implementasjoner allerede med pekere til medlems{variable,funksjoner}.
Jeg har svært ved at se den slags pointere som relevante for opgaven.
>> Footnotes: [1] Hvilket ikke er garanteret af sproget, men et
>> implicit eller eksplicit krav i mange projekter, f.eks. GNU.
>
>
> Nå kjenner jeg veldig dårlig memory modellen på i386, men ser gcc
> _helt_ bort fra segment registrene?
Det er ikke GCC men GNU jeg snakker om. GNU er fra starten af
designet til at køre på maskiner med mindst 1Mb fysisk memory og et
32bit fladt adresserum (i dag vil de også gerne kunne køre på maskiner
med 64bit adresserum).
Så vidt jeg husker er i386 en 40? 48? (> 32 bit) segmenteret
processor, men de fleste operativsystemer (inklusiv Linux og Win32)
vil normalt give hver process 32 bit flad memory, og GCC vil kun
generere kode der adresserer indenfor et enkelt 32bit segment, med
mindre man bruger GCC specifikke udvidelser. Jeg mener man
efterhånden kan bede om mere memory med særlige kald, men det vil ikke
kunne adresseres direkte med en C pointer.
| |
|
|