質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

Q&A

解決済

3回答

3455閲覧

memcpyのメモリについて

tyapapa

総合スコア51

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

0グッド

1クリップ

投稿2020/07/29 07:53

編集2020/07/30 12:49

C++

1int main() 2{ 3 uint8_t *Buff[100]; 4 uint32_t data = 100000; 5 6 memcpy(&Buff[0], &data, sizeof(data)); 7}

上記ような場合は、
memcpy実行後は、uint32のサイズ分であるBuff[0]~Buff[3]まで
変数dataの値が格納されているのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

C

1#include <stdio.h> // printf 2#include <string.h> // memcpy 3#include <stdint.h> // uint8_t, utin32_t 4 5int main(void) 6{ 7 uint8_t *Buff[100]; 8 uint32_t data = 100000; 9 10 memcpy(&Buff[0], &data, sizeof(data)); 11 printf("sizeof(Buff[0]) = %zd\n", sizeof(Buff[0])); 12 printf("data = %d (%#08x)\n", data, data); 13 for (int i = 0; i < 4; i++) 14 printf("Buff[%d] = %p\n", i, Buff[i]); 15}

64ビット版gcc による実行結果

sizeof(Buff[0]) = 8 data = 100000 (0x0186a0) Buff[0] = 0x186a0 Buff[1] = (nil) Buff[2] = 0x7fffd7a17fd0 Buff[3] = (nil)

ポインタが 8バイトなので 4バイトの値をコピーしても
下位4バイトに入るだけで、上位4バイトがゼロとは限りません。
Buff[0] = 0xXXXXXXXX000186a0 (X は不定) ととなる
可能性がありましたが、この例では偶然全部 0 でした。
Buff[1]、Buff[3]は 8バイト全部が 0 でした。
Buff[2] は何かゴミが入っています。
Buff 自体は自動変数なので初期化しないと何が入っているか分かりません。

私が不思議なのは、
質問者はどうして実行結果を自分で確かめようとしないのかということです。
確かめて、「自分はこういう結果になると思ったのに、違う結果が出てしまった。
なぜでしょうか?」と質問するべきなのです。

投稿2020/07/30 01:31

編集2020/07/30 01:52
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tyapapa

2020/07/30 12:42

ポインタは、uint8_tなのに8バイトなのですか? 確かに、自身で結果を確かめたから質問すべきでした。 急いでいたため失礼な形で質問してしまいました。すみません
kazuma-s

2020/07/30 14:45

uint8_t は 8ビットで 1バイトの符号なし整数で、0~255 の 256通りの値を取ります。 ポインタが 8ビットで 1バイトなら、256通りのアドレスしか取れません。 アドレスは何ギガバイトもあるので、32ビット4バイトとか64ビット8バイトになります。 ポインタの指す対象が 1バイトの char だろうが 4バイトの int だろうが 8バイトの double だろうが 24バイトの構造体だろうが、ポインタのサイズは 4バイトまたは 8バイトです。 ポインタの値はアドレスなのだから。 C が誕生したころの DEC社のミニコン PDP-11 は、アドレスが 16ビットだったので ポインタは 2バイトでした。その後の 8ビットマイコンや 16ビットマイコンもポインタは 2バイトでした。しかし、CPUが 32ビットになってからはポインタは 4バイトになりました。 今は 64ビット8バイトの時代です。
guest

0

コードはuint32_t、本文はuint16。
100000代入しているからuint32_tなんでしょうね。(本文修正しましょう)

ならばsizeof(data)の値は4なので、sizeof(uint8_t *)が4ならBuff[0]のみにコピーされるでしょう。

そもそもポインタ配列Buffにdataをコピーする意味が不明。

投稿2020/07/29 23:08

DreamTheater

総合スコア1095

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tyapapa

2020/07/30 12:54

uint8_tって1バイトですよね? なので4バイト分のBuff[0]~[3]にコピーされるもんだと考えてましたが、 違うのですね。 ポインタ配列にしている理由はたまたま見ていたコードが こうだったので書いてます。特別意味ないです。
DreamTheater

2020/07/30 22:14

uint8_tは1バイトでもそのポインタですよ? ポインタの大きさは非ポインタのデータ型に依存しません。 サイズという意味では非常に意味があります。
guest

0

同じとこから読んで同じとこにコピーしてるだけで、それは意味はありません

ちなみに、uint16_t の変数のサイズは2バイトです

投稿2020/07/29 07:55

編集2020/07/29 07:56
y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tyapapa

2020/07/29 07:58

指摘感謝します。文に誤りがありました。
y_waiwai

2020/07/29 08:00

これなら、Buffに、dataの2バイトがコピーされますね #しかし、dataの内容は、100000ではありません
dodox86

2020/07/29 08:01

>質問者さん ついでに指摘すれば、 uint8_t *Buff[100];は uint8_t Buff[100]; の間違いではないですか。(元は、ポインターの配列になっています)
tyapapa

2020/07/29 09:11

y_waiwai様 dataの内容が100000ではないとはなぜでしょうか?
tyapapa

2020/07/29 09:11

dodox86様 ポインタ配列で問題ないです。
y_waiwai

2020/07/29 09:15

ああ、uint32_tに変わってたのね。 それなら100000きっちり入ってますね #変数サイズは4バイト
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問