Hoe een geheugenadres in C af te drukken

Mijn code is:

#include <stdio.h>
#include <string.h>
void main()
    {
    char string[10];
    int A = -73;
    unsigned int B = 31337;
    strcpy(string, "sample");
    // printing with different formats
    printf("[A] Dec: %d, Hex: %x, Unsigned: %u\n", A,A,A);
    printf("[B] Dec: %d, Hex: %x, Unsigned: %u\n", B,B,B);
    printf("[field width on B] 3: '%3u', 10: '%10u', '%08u'\n", B,B,B);
    // Example of unary address operator (dereferencing) and a %x
    // format string 
    printf("variable A is at address: %08x\n", &A);

Ik gebruik de terminal in linux mint om te compileren, en wanneer ik probeer te compileren met gcc krijg ik de volgende foutmelding:

basicStringFormatting.c: In function ‘main’:
basicStringFormatting.c:18:2: warning: format ‘%x’ expects argument
of type ‘unsigned int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("variable A is at address: %08x\n", &A);

Het enige wat ik probeer te doen is het adres in het geheugen van de variabele A af te drukken.


Antwoord 1, autoriteit 100%

Gebruik de formaatspecificatie %p:

printf("variable A is at address: %p\n", (void*)&A);

De standaard vereist dat het argument van het type void*is voor de specificatie %p. Aangezien printfeen variadische functie is, is er geen impliciete conversie naar void *van T *, wat impliciet zou gebeuren voor alle niet-variadische functies in C. Daarom is de cast vereist. Om de norm te citeren:

7.21.6 Geformatteerde invoer-/uitvoerfuncties (C11-concept)

p Het argument zal een pointer naar void zijn. De waarde van de aanwijzer is
geconverteerd naar een reeks afdruktekens, in een
implementatie-gedefinieerde manier.

Terwijl u %xgebruikt, die unsigned intverwacht, terwijl &Avan het type int *. Je kunt lezen over formaatspecificaties voor printf in de handleiding. Niet-overeenkomende indelingsspecificaties in printf leiden tot ongedefinieerd gedrag.


Antwoord 2

Een tijdelijke oplossing om %xmet lengtespecificatie te gebruiken om een intof unsigned intaf te drukken zonder dat de compiler klaagt over casten, is om malloc te gebruiken :

unsigned int* D = malloc(sizeof(unsigned int)); // Allocate D
unsigned int D_address = *((unsigned int*) &D); // D address for %08x without warning
*D = 75; // D value
printf("variable D is at address: %p / 0x%08x with value: %u\n", D, D_address, *D);

Als alternatief kun je compileren met gcc -wflag om die castingwaarschuwingen te onderdrukken.

Other episodes