2010-08-29 25 views
5

Étant donné une adresse de mémoire littérale au format hexadécimal, comment puis-je créer un pointeur en C qui adresse cet emplacement de mémoire?littéral d'adresse mémoire

Les adresses de mémoire sur ma plate-forme (IBM iSeries) sont 128 bits. C type long long est également 128 bits.

Imagine I ont une adresse de mémoire pour une chaîne de caractères (tableau de caractères) qui est: C622D0129B0129F0

Je suppose que la syntaxe correcte C pour répondre directement à cet emplacement de mémoire:

const char* const p = (const char* const)0xC622D0129B0129F0ULL

J'utilise ULL suffixe indique non signé long long littéral. Si mon noyau/plate-forme/système d'exploitation me permettra de faire ceci est une question différente. Je veux d'abord savoir si ma syntaxe est correcte.

+3

Enfer d'un espace d'adressage. – GManNickG

+0

C'est ce qu'était l'AS/400. Enfer d'une machine en général. –

Répondre

12

Votre syntaxe est presque correcte. Vous n'avez pas besoin de ceux const:

const char* const p = (const char*)0xC622D0129B0129F0ULL 

Le const immédiatement avant p indique que la variable p ne peut pas être changé après l'initialisation. Il ne se réfère à rien sur ce que p points, de sorte que vous n'en avez pas besoin sur le côté droit.

+0

Le compilateur l'acceptant est un bon point de départ, mais ne garantit pas la conformité aux normes. De nombreuses extensions sont implémentées dans les compilateurs. Cela dit, oui, cela semble correct. –

+1

Non, il s'agit d'un comportement indéfini. Seule la conversion en 'void *' est censée donner quelque chose de correct et 'uintptr_t' pourrait être différent de' unsigned long long' (bien que peu probable dans ce cas) –

+2

Jens a tort - le comportement est défini par l'implémentation, * pas * undefined – Christoph

0

Il n'y a pas une telle chose comme une adresse littérale en C.

La seule chose qui est garanti pour travailler entre les nombres entiers et pointeurs est lancé à partir void* à uintptr_t (si elle existe), puis de nouveau. Si vous avez obtenu votre adresse de quelque part sous la forme d'un entier, cela devrait être de type uintptr_t. Utilisez quelque chose comme

(void*)(uintptr_t)UINTMAX_C(0xC622D0129B0129F0) 

pour le reconvertir.

Vous devez inclure stdint.h pour obtenir le type uintptr_t et la macro UINTMAX_C.

+0

-1: C99 ne définit que les macros pour les constantes de largeur minimale et de largeur maximale - il n'y a pas de macro 'UINTPTR_C()' dans 'stdint.h' – Christoph

+0

@Christoph: Votre seconde assertion est correcte. Je vais modifier ma réponse en conséquence. –

+0

supprimé downvote; corrigé le '0x' manquant aussi ... – Christoph