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

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

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

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

1903閲覧

C++ アドレスの代入

gozi

総合スコア17

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/10/08 15:14

出題された問いを解いている最中で詰まってしまったので、質問させていただきます。

C++

1typedef unsigned char BYTE; 2 3// 問題で決まっている定数 4#define value 0x800000; 5 6void main() { 7 BYTE* hoge; 8 // アドレスを初期化 9 hoge = (BYTE*)value; 10 11 // 指定アドレスの値を初期化 12 *hoge = 1 << 0; // エラー 13 14 // 以降、hoge番地のbitを見てそれに応じた処理 15}

扱うオブジェクトは複数あって、次の指定アドレスが0x800001です。

エラー内容は文字列の文字の読み取り~となっているので、文字コード0x800000番の文字なんてありませんよ。と言われているのだと解釈しています。

typedefをcharにしているのが原因かとも考えましたが、指定アドレスが1Byteずつになっているのでchara以外ではダメだしなぁといった具合です。

問題点がいまいち見えていないので、エラーの吐いている定数(指定アドレス)代入を題にさせていただきました。
Byte,bitでの考え方には全然慣れておらず、変な考え方や簡単なところを見落としているのかとも思いますが、よろしくお願いいたします。

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

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

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

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

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

guest

回答4

0

組み込み系で、アドレスが指定されているとか?

そうでないならば、固定アドレス指定は普通しません。OSを介して決めるの普通です。多分、課題の全体が書かれていません。

投稿2018/10/08 15:44

HogeAnimalLover

総合スコア4830

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

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

gozi

2018/10/08 16:14

そのとおりです。
guest

0

エラーの内容をそのまま提示してください

組み込み用途であれば、アドレス直書きでのアクセスは珍しくないですが、その提示されたソースの実行環境は何でしょうか。
PCで実行している、というのであればエラーが出て当然です。

投稿2018/10/08 16:36

y_waiwai

総合スコア87774

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

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

gozi

2018/10/08 17:34

PCでの実行です
guest

0

ベストアンサー

どのような意図の問題なのでしょうか?

あなたの今のコードは以下のような状態になっています。

cpp

1#include <iostream> 2 3typedef unsigned char BYTE; 4 5// 問題で決まっている定数 6#define value 0x800000; 7 8void main() 9{ 10 BYTE *hoge; 11 hoge = (BYTE *)value; // アドレス 0x800000を指すポインタ 12 std::cout << hoge << std::endl; // 0000000000800000 13 14 // 指定アドレスの値を初期化 15 *hoge = 1 << 0; // アドレス 0x800000 に変数が確保されているわけではないので、代入すると、メモリの不正アクセスになり、落ちる。 16}

追記

組み込みはわかりませんが、Windows や Linux の場合、メモリは OS が管理しており、プログラムは OS に割り当てられたプロセスメモリ空間を参照します。

物理アドレス空間と仮想アドレス空間の違いとその基礎知識

今回の問題点

問題点は文字列の文字の~というやつではなく、アドレスの値を初期化の部分なのか

今回の問題点は、値 1 << 0 つまり 1 をアドレス 0x800000 番地にセットしようとしたが、その領域に BYTE 型の変数領域が確保されていなかったためです。

他の回答者様がご指摘されているとおり、malloc() や new でメモリ領域を確保して、割り当てられたメモリを使うのが普通です。

BYTE* p = new BYTE; *p = 1; printf("p = %p\n", p); // 00000244554A30A0 割り当てられたメモリアドレス printf("*p = %d\n", *p); // 1

任意のアドレスに確保することは不可能なのか

OS 依存の問題です。
Windows では、VirtualAlloc で指定したアドレスのメモリを確保できます。

cpp

1#include <iostream> 2#include <windows.h> 3 4typedef unsigned char BYTE; 5#define value 0x800000 // ; は不要 6 7void main() 8{ 9 BYTE *ptr = (BYTE *)value; // アドレス 0x800000を指すポインタ 10 printf("ptr = %p\n", ptr); // ptr = 0000000000800000 11 12 // 0x800000 番地を予約する。予約に失敗した場合は NULL が返る。 13 ptr = (BYTE *)VirtualAlloc( 14 (LPVOID)ptr, sizeof(BYTE), MEM_RESERVE, PAGE_READWRITE); 15 if (ptr) 16 // 予約に成功した場合、確保する。 17 ptr = (BYTE *)VirtualAlloc( 18 (LPVOID)ptr, sizeof(BYTE), MEM_COMMIT, PAGE_READWRITE); 19 20 *ptr = 1 << 0; // 1b 21 printf("*ptr = %d\n", *ptr); // 1 22 23 *ptr = 1 << 1; // 10b 24 printf("*ptr = %d\n", *ptr); // 2 25}

その他

もし組み込みOSなど Linux/Windows 以外の特殊な環境の場合は、その事も質問欄に追記したほうがよいかと思います。

投稿2018/10/08 15:39

編集2018/10/08 17:04
tiitoi

総合スコア21956

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

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

gozi

2018/10/08 16:22

私の理解していない部分も踏まえるとメモリアクセスの理解と取ってもらって間違いないと思います。 申し訳ございません。質問にも書いた通り不慣れなもので恐らく何が分からないのか分からないという状態になっているのだとおもいます。 とりあえず疑問に感じていることを書かせていただきます。 問題点は文字列の文字の~というやつではなく、アドレスの値を初期化の部分なのか 任意の変数(今回では 1<< 0 )を任意のアドレスに確保することは不可能なのか typedef unsignd char ではなく、intなのは間違いなのか、どちらでも同じ理由でエラーだから意図したことなのか どうぞよろしくお願い致します。
tiitoi

2018/10/08 17:04

typedef unsignd int は転記ミスです。失礼しました。
gozi

2018/10/08 17:33

動作確認しました。 ただ、予約という事でどこに何が割り当てられるのか分からない以上失敗の可能性もあるのですね。 少し前進することができたので、windowsの機能をもう少し読み進めた上で 問題点を明確化していきたいと思います。 ありがとうございました。
guest

0

出題された問い

環境が判らないのでなんとも言えませんが、今時のOSで固定番地のアクセスは出来ないはずですが・・・
出題自体に問題がありそうですが、どうなんでしょう?

投稿2018/10/08 15:38

cateye

総合スコア6851

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

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

gozi

2018/10/08 16:15

おかしかったとしても、他にいただいた回答なども踏まえておかしいと納得できるまでは深めたいと考えています。
cateye

2018/10/08 16:28 編集

0x800000番地って有りますか?・・・12.8Gです >*hoge = 1 << 0; // エラー については0x800000番地に1(1を0ビットシフト)を入れてるだけですd^^
gozi

2018/10/08 17:36

触ってきたものが少ないせいか数値を見ただけでは疑問は浮かばなかったですね
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問