web-dev-qa-db-ja.com

Cで変数のメモリ内容を出力するにはどうすればよいですか?

私がすることを仮定します

double d = 234.5;

d [8バイト全体]のメモリの内容を確認したい

どうすればいいですか?

24
Lazer
double d = 234.5;

/* 1. use a union */
union u {
    double d;
    unsigned char c[sizeof(double)];
};
union u tmp;
size_t i;
tmp.d = d;
for (i=0; i < sizeof(double); ++i)
    printf("%02x\n", tmp.c[i]);

/* 2. memcpy */
unsigned char data[sizeof d];
size_t i;
memcpy(data, &d, sizeof d);
for (i=0; i < sizeof d; ++i)
    printf("%02x\n", data[i]);

/* 3. Use a pointer to an unsigned char to examine the bytes */
unsigned char *p = (unsigned char *)&d;
size_t i;
for (i=0; i < sizeof d; ++i)
    printf("%02x\n", p[i]);

すべてのメソッドでバイトが表示されますが、同じdouble値は、エンコード(まれ)やエンディアンが異なるなど、システムによってバイトの出力が異なる場合があります。

20
Alok Singhal
unsigned char *p = (unsigned char *)&d;
int i;

for (i = 0; i < sizeof d; i++)
    printf("%02x ", p[i]);
27
caf

便利なスニペットのライブラリのおかげで、これがCのソリューションであり、テストハーネスを備え、16進数とASCIIデータの両方を提供します:

_#include <stdio.h>

void hexDump (char *desc, void *addr, int len) {
    int i;
    unsigned char buff[17];       // stores the ASCII data
    unsigned char *pc = addr;     // cast to make the code cleaner.

    // Output description if given.

    if (desc != NULL)
        printf ("%s:\n", desc);

    // Process every byte in the data.

    for (i = 0; i < len; i++) {
        // Multiple of 16 means new line (with line offset).

        if ((i % 16) == 0) {
            // Just don't print ASCII for the zeroth line.

            if (i != 0)
                printf ("  %s\n", buff);

            // Output the offset.

            printf ("  %04x ", i);
        }

        // Now the hex code for the specific character.

        printf (" %02x", pc[i]);

        // And store a printable ASCII character for later.

        if ((pc[i] < 0x20) || (pc[i] > 0x7e))
            buff[i % 16] = '.';
        else
            buff[i % 16] = pc[i];
        buff[(i % 16) + 1] = '\0';
    }

    // Pad out last line if not exactly 16 characters.

    while ((i % 16) != 0) {
        printf ("   ");
        i++;
    }

    // And print the final ASCII bit.

    printf ("  %s\n", buff);
}

int main (int argc, char *argv[]) {
    double d1 = 234.5;
    char s1[] = "a 15char string";
    char s2[] = "This is a slightly longer string";
    hexDump ("d1", &d1, sizeof d1);
    hexDump ("s1", &s1, sizeof s1);
    hexDump ("s2", &s2, sizeof s2);
    return 0;
}
_

私のシステムの出力は次のとおりです。

_d1:
  0000  00 00 00 00 00 50 6d 40                          .....Pm@
s1:
  0000  61 20 31 35 63 68 61 72 20 73 74 72 69 6e 67 00  a 15char string.
s2:
  0000  54 68 69 73 20 69 73 20 61 20 73 6c 69 67 68 74  This is a slight
  0010  6c 79 20 6c 6f 6e 67 65 72 20 73 74 72 69 6e 67  ly longer string
  0020  00                                               .
_

この質問にもC++のタグが付いているので、比較するiostreamバージョンを次に示します。 iostreamの特定のファンでなくても、すでにiostreamを使用している場合は、それでも適合します。 hexdump(any_obj)を使用できることも素晴らしいですが、もちろん、ctorと同様の委任関数テンプレートを使用して実行できます。

_#include <iomanip>
#include <ostream>
#include <string>

struct hexdump {
  void const* data;
  int len;

  hexdump(void const* data, int len) : data(data), len(len) {}

  template<class T>
  hexdump(T const& v) : data(&v), len(sizeof v) {}

  friend
  std::ostream& operator<<(std::ostream& s, hexdump const& v) {
    // don't change formatting for s
    std::ostream out (s.rdbuf());
    out << std::hex << std::setfill('0');

    unsigned char const* pc = reinterpret_cast<unsigned char const*>(v.data);

    std::string buf;
    buf.reserve(17); // premature optimization

    int i;
    for (i = 0; i < v.len; ++i, ++pc) {
      if ((i % 16) == 0) {
        if (i) {
          out << "  " << buf << '\n';
          buf.clear();
        }
        out << "  " << std::setw(4) << i << ' ';
      }

      out << ' ' << std::setw(2) << unsigned(*pc);
      buf += (0x20 <= *pc && *pc <= 0x7e) ? *pc : '.';
    }
    if (i % 16) {
      char const* spaces16x3 = "                                                ";
      out << &spaces16x3[3 * (i % 16)];
    }
    out << "  " << buf << '\n';

    return s;
  }
};

int main() {
  std::cout << "double:\n" << hexdump(234.5);
  std::cout << "string 1:\n" << hexdump("a 15char string");
  std::cout << "string 2:\n" << hexdump("This is a slightly longer string");

  return 0;
}
_
8
paxdiablo

ダブル値をビット単位で出力したい場合は、これを試してください。浮動小数点値を試しました。これを変更した場合は、64ビットでdouble値を表示できます。

#include <stdio.h>

int main (void)
{
        float f = 10.0f;

        struct Float {
                unsigned char bit01:1;
                unsigned char bit02:1;
                unsigned char bit03:1;
                unsigned char bit04:1;
                unsigned char bit05:1;
                unsigned char bit06:1;
                unsigned char bit07:1;
                unsigned char bit08:1;
                unsigned char bit09:1;
                unsigned char bit10:1;
                unsigned char bit11:1;
                unsigned char bit12:1;
                unsigned char bit13:1;
                unsigned char bit14:1;
                unsigned char bit15:1;
                unsigned char bit16:1;
                unsigned char bit17:1;
                unsigned char bit18:1;
                unsigned char bit19:1;
                unsigned char bit20:1;
                unsigned char bit21:1;
                unsigned char bit22:1;
                unsigned char bit23:1;
                unsigned char bit24:1;
                unsigned char bit25:1;
                unsigned char bit26:1;
                unsigned char bit27:1;
                unsigned char bit28:1;
                unsigned char bit29:1;
                unsigned char bit30:1;
                unsigned char bit31:1;
                unsigned char bit32:1;
        };

        struct Float *F;

        F = (struct Float *) &f;

        printf("\nMSB -->1 bit for sign bit; 8 bit for exponent; 23 bit for mantisa<-- LSB\n");
        printf("%d ", F->bit32);
        printf("%d", F->bit31);
        printf("%d", F->bit30);
        printf("%d", F->bit29);
        printf("%d", F->bit28);
        printf("%d", F->bit27);
        printf("%d", F->bit26);
        printf("%d", F->bit25);
        printf("%d ", F->bit24);
        printf("%d", F->bit23);
        printf("%d", F->bit22);
        printf("%d", F->bit21);
        printf("%d", F->bit20);
        printf("%d", F->bit19);
        printf("%d", F->bit18);
        printf("%d", F->bit17);
        printf("%d", F->bit16);
        printf("%d", F->bit15);
        printf("%d", F->bit14);
        printf("%d", F->bit13);
        printf("%d", F->bit12);
        printf("%d", F->bit11);
        printf("%d", F->bit10);
        printf("%d", F->bit09);
        printf("%d", F->bit08);
        printf("%d", F->bit07);
        printf("%d", F->bit06);
        printf("%d", F->bit05);
        printf("%d", F->bit04);
        printf("%d", F->bit03);
        printf("%d", F->bit02);
        printf("%d\n", F->bit01);
}
2
sganesh

試してみてください

union Plop
{
    double   value;
    char     data[sizeof(double)];
};

Plop print;
print.value = 234.5;

std::copy(print.data,print.data+sizeof(double),std::ostream_iterator<int>(std::cout)," ");
std::cout << std::endl;
2
Martin York

Gdbからこれを表示したい場合は、以下を発行できます。

x /gx d

Gは値をジャイアント(8バイト)として出力します

2
nall

dのアドレスを取得し、そのアドレスからsizeof( d )バイトを出力してみましたか?

1
Arun

使いやすいデバッガーを使用することは、メモリ位置の値を確認するための最良の方法です。つまり、uだけを確認したい場合です。

1
the100rabh

シフト操作とマスクを使用して、実際のビットを「マスクアウト」できると思います。

int t = 128;

for(int i = 0; i <8; ++ i){printf( "%d"、p&t);

p = >> 1;

t = >> 1; }

0
Zhimin Zong