<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Datentyp von Adressen? &amp;amp; Pointerarithmetik overflow?!]]></title><description><![CDATA[<p>Hallo,<br />
ja das sind eigentlich auch schon meine beiden Fragen..<br />
Was ist eigentlich der Datentyp von Pointerwerten?<br />
Mich interessiert dabei eigentlich der Wertebereich, und, dass ich die daten nicht konvertieren muss, wenn ich mal ne Zahl auf einen Pointer addiere usw.<br />
Ich tippe auf &quot;unsigned long&quot;. Weiß das jemand und evtl auch warum..?<br />
z.B.</p>
<pre><code>char k = 5;
unsigned long h = 5;
void *p = &amp;xyz + k; // schlecht
void *p = &amp;xyz + h; // gut, evtl..
</code></pre>
<p>Und ist es möglich den Wertebereich zu verlassen, bei sowas wie:</p>
<pre><code>int *p = &amp;xyz;
p +-= 1;
</code></pre>
<p>Oder gibt es zumindest bei Betriebssystemen die Gewissheit, dass die ersten und letzten paar Adressen nie einem Pointer aus dem Programm zugewiesen werden?</p>
<p>PS. Pointer werden mathematisch doch genauso behandelt wie ints, oder?!</p>
<p>Gruß,<br />
Funzel</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/339118/datentyp-von-adressen-amp-pointerarithmetik-overflow</link><generator>RSS for Node</generator><lastBuildDate>Sun, 12 Apr 2026 16:39:22 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/339118.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 03 Aug 2016 17:18:59 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Datentyp von Adressen? &amp;amp; Pointerarithmetik overflow?! on Wed, 03 Aug 2016 17:18:59 GMT]]></title><description><![CDATA[<p>Hallo,<br />
ja das sind eigentlich auch schon meine beiden Fragen..<br />
Was ist eigentlich der Datentyp von Pointerwerten?<br />
Mich interessiert dabei eigentlich der Wertebereich, und, dass ich die daten nicht konvertieren muss, wenn ich mal ne Zahl auf einen Pointer addiere usw.<br />
Ich tippe auf &quot;unsigned long&quot;. Weiß das jemand und evtl auch warum..?<br />
z.B.</p>
<pre><code>char k = 5;
unsigned long h = 5;
void *p = &amp;xyz + k; // schlecht
void *p = &amp;xyz + h; // gut, evtl..
</code></pre>
<p>Und ist es möglich den Wertebereich zu verlassen, bei sowas wie:</p>
<pre><code>int *p = &amp;xyz;
p +-= 1;
</code></pre>
<p>Oder gibt es zumindest bei Betriebssystemen die Gewissheit, dass die ersten und letzten paar Adressen nie einem Pointer aus dem Programm zugewiesen werden?</p>
<p>PS. Pointer werden mathematisch doch genauso behandelt wie ints, oder?!</p>
<p>Gruß,<br />
Funzel</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2504526</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504526</guid><dc:creator><![CDATA[Funzel]]></dc:creator><pubDate>Wed, 03 Aug 2016 17:18:59 GMT</pubDate></item><item><title><![CDATA[Reply to Datentyp von Adressen? &amp;amp; Pointerarithmetik overflow?! on Wed, 03 Aug 2016 17:41:40 GMT]]></title><description><![CDATA[<p>Funzel schrieb:</p>
<blockquote>
<p>PS. Pointer werden mathematisch doch genauso behandelt wie ints, oder?!</p>
</blockquote>
<p>Nein, denn bei der Addition von Ganzzahlwerten, wird die Größe des Elements auf das der Pointer zeigt berücksichtigt.</p>
<p>Aus dem Grund kannst du zu einem (ungecasteten) void-Pointer auch nichts addieren.</p>
<p>Additionen, Multiplikation und Division von zwei Pointern ist auch nicht möglich.</p>
<p>Was soll der +-= Operator machen?</p>
<p>Du kannst einem Pointer jede beliebige Adresse zuweisen. Ob die zu deinem Programm gehört, steht auf einem anderen Blatt. Das Alignement auch.</p>
<p>Den Wertebereich kannst du mit sizeof an der Größe abschätzen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2504528</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504528</guid><dc:creator><![CDATA[DirkB]]></dc:creator><pubDate>Wed, 03 Aug 2016 17:41:40 GMT</pubDate></item><item><title><![CDATA[Reply to Datentyp von Adressen? &amp;amp; Pointerarithmetik overflow?! on Wed, 03 Aug 2016 17:48:10 GMT]]></title><description><![CDATA[<p>Differenz zwischen zwei Zeigern: <a href="http://en.cppreference.com/w/cpp/types/ptrdiff_t" rel="nofollow">ptrdiff_t</a><br />
Datentyp von Adressen: Zeiger auf Objekt auf das man den Adressoperator angewendet hat.</p>
<p>Wenn es unbedingt sein muss, und ich betone, dass du höchstwahrscheinlich etwas krass falsch machst, wenn du dies außerhalb der Programmierung von ganz low-leveligen Sachen benutzt, gibt es noch <a href="http://en.cppreference.com/w/cpp/types/integer" rel="nofollow">(u)intptr_t</a>, welches ein Integer ist, der <em>mindestens</em> den ganzen Wertebereich eines void-Pointers verlustfrei abbilden kann.</p>
<p>Funzel schrieb:</p>
<blockquote>
<p>PS. Pointer werden mathematisch doch genauso behandelt wie ints, oder?!</p>
</blockquote>
<p>Nein, überhaupt nicht. Zu Pointern kann man Integer addieren und man kann die Differenz von zwei Pointern berechnen. Das ist alles, was man mit Pointern rechnen kann. Und die Regeln für diese Rechnungen sind ganz andere, als wenn man den Zeiger im Sinne eines uintptr_t interpretieren würde und mit diesem die Rechnung durchführen würde.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2504529</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504529</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Wed, 03 Aug 2016 17:48:10 GMT</pubDate></item><item><title><![CDATA[Reply to Datentyp von Adressen? &amp;amp; Pointerarithmetik overflow?! on Wed, 03 Aug 2016 18:35:53 GMT]]></title><description><![CDATA[<blockquote>
<p>Aus dem Grund kannst du zu einem (ungecasteten) void-Pointer auch nichts addieren.</p>
</blockquote>
<p>Dann war das natürlich ein unglückliches Beispiel.<br />
Wie wärs dann hiermit:</p>
<pre><code>char k = 5;
unsigned long h = 5;
float *a = &amp;xyz + k;
float *b = &amp;xyz + h;
float *c = &amp;xyz + 5; // oder 5u etc.. ?
</code></pre>
<blockquote>
<p>Was soll der +-= Operator machen?</p>
</blockquote>
<p>Entweder &quot;+=&quot; oder &quot;-=&quot;.</p>
<p>Es könnte ja sein, dass der Speicher von &quot;0&quot; beginnend aufgefüllt wird. Wenn also mein Programm gestartet wird, wären die ersten paar Adressen schon belegt (vom OS etc.). Dann könnte ich mir sicher sein, dass kein Pointer in meinem Programm auf z.B. 0x0, oder 0x1 zeigt und bei &quot;-= 5&quot; den Wertebereich verlässt...<br />
Entsprechendes könnte für das andere Ende des Speichers gelten.<br />
So stell ich mir das vor..</p>
<p>Und jetzt frage ich mich natürlich nach welchen Regeln die typedefs erstellt wurden..?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2504535</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504535</guid><dc:creator><![CDATA[Funzel]]></dc:creator><pubDate>Wed, 03 Aug 2016 18:35:53 GMT</pubDate></item><item><title><![CDATA[Reply to Datentyp von Adressen? &amp;amp; Pointerarithmetik overflow?! on Wed, 03 Aug 2016 18:44:55 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>Wenn es unbedingt sein muss, und ich betone, dass du höchstwahrscheinlich etwas krass falsch machst, wenn du dies außerhalb der Programmierung von ganz low-leveligen Sachen benutzt, gibt es noch <a href="http://en.cppreference.com/w/cpp/types/integer" rel="nofollow">(u)intptr_t</a>, welches ein Integer ist, der <em>mindestens</em> den ganzen Wertebereich eines void-Pointers verlustfrei abbilden kann.</p>
</blockquote>
<p>Beim Parsen von Binärdaten (MZ-/ELF-Headern, Netzwerkpaketen etc.) hat man nicht den Luxus, einfach eine Struktur für den Zugriff draufzuknallen. Stattdessen hat man dann die Anzahl der Bytes ab Beginn eines Referenzpunktes. Auf diesen muss man dann die Anzahl der Bytes addieren, damit man zu den Daten kommt. Der Check, um zu prüfen, ob sich die Daten innerhalb des Pakets befinden, sieht dann so aus:</p>
<pre><code>uintptr_t begin_uintptr = (uintptr_t)begin_ptr;
uintptr_t end_uintptr   = (uintptr_t)end_ptr;
uintptr_t new_uintptr   = begin_uintptr + bytes;

if(new_uintptr  &lt; begin_uintptr)
|| new_uintptr &gt;= end_uintptr)
    return EOVERFLOW;
</code></pre>
<p>Der erste Check prüft auf Overflow der Adresse. Wenn man das nicht tut, kann am Ende der Wert überlaufen, und der zweite Check, der prüft, ob die Adresse noch im Bereich liegt, kann das nicht merken. Um nicht undefinierte Pointerarithmetik zu machen muss man in <code>uintptr_t</code> s casten. Das würde ich nicht unbedingt low-levelig bezeichnen.</p>
<p>@TE:<br />
Und nicht <code>size_t</code> mit <code>uintptr_t</code> verwechseln, da gibt es subtile Unterschiede zwischen den Typen. Nimm für Pointerberechnungen immer <code>uintptr_t</code> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2504537</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504537</guid><dc:creator><![CDATA[dachschaden]]></dc:creator><pubDate>Wed, 03 Aug 2016 18:44:55 GMT</pubDate></item><item><title><![CDATA[Reply to Datentyp von Adressen? &amp;amp; Pointerarithmetik overflow?! on Wed, 03 Aug 2016 18:48:38 GMT]]></title><description><![CDATA[<p>Was ist denn xyz?</p>
<p>Wenn du auf Speicher zugreifen möchtest, der dir (deinem Programm) nicht gehört, hast du UB.<br />
Da darf alles passieren.</p>
<p>Wenn du auf deinem System ein bestimmtes Verhalten ermittelt hast, dann kann das bei einem anderen System, Compiler, Compilerversion wieder anders sein.</p>
<pre><code>float y[3] = { 1, 2, 3];
float *fp = &amp;y[1];
</code></pre>
<p>Dann greifst du mit *(fp+1) auf y[2] und mit *(fp-1) auf y[0] zu.</p>
<pre><code>float x = 1, y = 2, z = 3;
float *fp = &amp;y;
</code></pre>
<p>Dann <strong>kann</strong> es sein, dass du mit *(fp+1) auf z und mit *(fp-1) auf x zugreifen kannst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2504538</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504538</guid><dc:creator><![CDATA[DirkB]]></dc:creator><pubDate>Wed, 03 Aug 2016 18:48:38 GMT</pubDate></item><item><title><![CDATA[Reply to Datentyp von Adressen? &amp;amp; Pointerarithmetik overflow?! on Wed, 03 Aug 2016 19:45:58 GMT]]></title><description><![CDATA[<p>dachschaden schrieb:</p>
<blockquote>
<pre><code>uintptr_t begin_uintptr = (uintptr_t)begin_ptr;
uintptr_t end_uintptr   = (uintptr_t)end_ptr;
uintptr_t new_uintptr   = begin_uintptr + bytes;

if(new_uintptr  &lt; begin_uintptr)
|| new_uintptr &gt;= end_uintptr)
    return EOVERFLOW;
</code></pre>
<p>Der erste Check prüft auf Overflow der Adresse. Wenn man das nicht tut, kann am Ende der Wert überlaufen, und der zweite Check, der prüft, ob die Adresse noch im Bereich liegt, kann das nicht merken. Um nicht undefinierte Pointerarithmetik zu machen muss man in <code>uintptr_t</code> s casten. Das würde ich nicht unbedingt low-levelig bezeichnen.</p>
</blockquote>
<p>Warum nicht <code>end_ptr - begin_ptr &gt;= bytes</code> ?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2504549</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504549</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Wed, 03 Aug 2016 19:45:58 GMT</pubDate></item><item><title><![CDATA[Reply to Datentyp von Adressen? &amp;amp; Pointerarithmetik overflow?! on Wed, 03 Aug 2016 19:48:10 GMT]]></title><description><![CDATA[<blockquote>
<p>Was ist denn xyz?</p>
<p>Wenn du auf Speicher zugreifen möchtest, der dir (deinem Programm) nicht gehört, hast du UB.<br />
Da darf alles passieren.</p>
</blockquote>
<p>xyz sei z.B. ein Array. Ist aber nicht wichtig, da ich nicht auf Speicher zugreife, der mir nicht gehört. Es geht mir nur darum, dass ich z.B. bei einem Zwischenschritt einer Rechnung mit Pointern, bei dem nicht dereferenziert wird, nicht den Wertebereich verlasse oder überlaufe.</p>
<pre><code>char k = 5;
unsigned long h = 5;
float *a = &amp;xyz + k;
float *b = &amp;xyz + h;
float *c = &amp;xyz + 5; // oder 5u etc.. ?
</code></pre>
<p>Also was ist &quot;besser&quot;/performanter, - a oder b? Und welches Literal nehme ich bei c ??</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2504551</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504551</guid><dc:creator><![CDATA[Funzel]]></dc:creator><pubDate>Wed, 03 Aug 2016 19:48:10 GMT</pubDate></item><item><title><![CDATA[Reply to Datentyp von Adressen? &amp;amp; Pointerarithmetik overflow?! on Wed, 03 Aug 2016 20:23:58 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>Warum nicht <code>end_ptr - begin_ptr &gt;= bytes</code> ?</p>
</blockquote>
<p>Weil ich keine Mutmaßungen darüber treffe, was <code>begin_ptr</code> und <code>end_ptr</code> für einen Typ haben.</p>
<pre><code>#include &lt;stdint.h&gt;
#include &lt;stdio.h&gt;

typedef uint32_t* myptr;

int main(void)
{
        myptr a = (myptr)0x1,b = (myptr)0x4;
        uintptr_t ua = (uintptr_t)a, ub = (uintptr_t)b;

        printf(&quot;%lx|%lx\n&quot;,b - a,ub - ua);
        return 0;
}
</code></pre>
<p>Ergebnis:</p>
<pre><code>0|3
</code></pre>
<p>Und wenn <code>myptr</code> als <code>void*</code> definiert wird, kompiliert es nicht einmal mehr mit Visual Studio.</p>
<pre><code>error C2036: &quot;myptr&quot;: Unbekannte Größe
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2504556</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504556</guid><dc:creator><![CDATA[dachschaden]]></dc:creator><pubDate>Wed, 03 Aug 2016 20:23:58 GMT</pubDate></item><item><title><![CDATA[Reply to Datentyp von Adressen? &amp;amp; Pointerarithmetik overflow?! on Wed, 03 Aug 2016 20:30:20 GMT]]></title><description><![CDATA[<p>dachschaden schrieb:</p>
<blockquote>
<p>SeppJ schrieb:</p>
<blockquote>
<p>Warum nicht <code>end_ptr - begin_ptr &gt;= bytes</code> ?</p>
</blockquote>
<p>Weil ich keine Mutmaßungen darüber treffe, was <code>begin_ptr</code> und <code>end_ptr</code> für einen Typ haben.</p>
</blockquote>
<p>Wieso nicht? Wenn es darum geht, irgendwelche Einzelbyteoffsets zu einem Pointer hinzu zu rechnen, dann ist der einzig korrekte Typ für diesen Pointer <code>char*</code> . Und es ist sogar völlig legitim, einen anderen Pointer zu <code>char*</code> zu casten, um solche Operationen durchzuführen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2504558</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504558</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Wed, 03 Aug 2016 20:30:20 GMT</pubDate></item><item><title><![CDATA[Reply to Datentyp von Adressen? &amp;amp; Pointerarithmetik overflow?! on Wed, 03 Aug 2016 20:35:54 GMT]]></title><description><![CDATA[<p>Funzel schrieb:</p>
<blockquote>
<pre><code>char k = 5;
unsigned long h = 5;
float *a = &amp;xyz + k;
float *b = &amp;xyz + h;
float *c = &amp;xyz + 5; // oder 5u etc.. ?
</code></pre>
<p>Also was ist &quot;besser&quot;/performanter, - a oder b?</p>
</blockquote>
<p>Möglicherweise b, aber aus anderen Gründen als du denkst.</p>
<blockquote>
<p>Und welches Literal nehme ich bei c ??</p>
</blockquote>
<p>Wie sollte das eine Rolle spielen? Meinst du, der Compiler würde Code erzeugen, um den Typ eines unpassenden Literals zur Laufzeit zu konvertieren, anstatt gleich den passenden Typ ins Programm einzubauen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2504559</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504559</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Wed, 03 Aug 2016 20:35:54 GMT</pubDate></item><item><title><![CDATA[Reply to Datentyp von Adressen? &amp;amp; Pointerarithmetik overflow?! on Wed, 03 Aug 2016 21:14:27 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>Wieso nicht? Wenn es darum geht, irgendwelche Einzelbyteoffsets zu einem Pointer hinzu zu rechnen, dann ist der einzig korrekte Typ für diesen Pointer <code>char*</code> . Und es ist sogar völlig legitim, einen anderen Pointer zu <code>char*</code> zu casten, um solche Operationen durchzuführen.</p>
</blockquote>
<p>Das war ein verkürztes Beispiel. Im Land der Realität habe ich einen Zeiger auf irgendein <code>struct</code> , mit Header-Daten, in denen sich das Offset befindet, welches man auf den Zeiger auf <code>struct</code> addieren muss. ELF mag das ganz besonders. Oder IP. Oder TCP. Oder sogar HTTP mit seiner Chunk-basierten Übertragung.</p>
<p>EDIT: Und wenn man auf Frickelcode genau wenig Lust hat wie ich, dann baut man sich vorher noch Code, der auf Overflow prüfen kann. Da verwendet man dann direkt <code>uintptr</code> im Makro oder in einer eingebundenen Funktion.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2504566</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2504566</guid><dc:creator><![CDATA[dachschaden]]></dc:creator><pubDate>Wed, 03 Aug 2016 21:14:27 GMT</pubDate></item></channel></rss>