mallocでメモリを確保して操作する様子を、ヒープを直に見ることで、観察する（Visual Studio 2017を使って）

プログラミングがよくわからん。今まで付け焼き刃でやってきたけど、もう限界。よし、基礎から勉強しよう。しかし元旦にやることじゃないよなー、ってもう2日か。しかし、思い立ったが吉日なのである！

### 目的

メモリ（仮想かもしれません）への書き込みをじかに見ることで、結局コードを実行するということは「メモリ（プログラム領域を含む）とCPUとのやりとり」なんだな、と1階層下の事象に落とし込む。

### 概要

mallocしたときのポインタの値を見て、Visual StudioのDebugメニューのMemory windowを表示して、その値をアドレスバーに入れると、直にそのメモリ位置のダンプが見えます。その状態でポインタを使うコードをステップ実行して、様子を見ます。

### 準備

[ビルドおよび C\+\+ コンソール アプリ プロジェクトの実行 \| Microsoft Docs](https://docs.microsoft.com/ja-jp/cpp/build/vscpp-step-2-build?view=vs-2017)

書かれているとおりにすればできます。

### 方法

#### コーディングの準備をする

![Start Page - Microsoft Visual Studio 2019-01-02 03.57.04.png](https://qiita-image-store.s3.amazonaws.com/0/12939/0febf5fd-e16e-91e5-2a79-0add57b27058.png)

新規プロジェクトを作成します。

![New Project 2019-01-02 03.59.36.png](https://qiita-image-store.s3.amazonaws.com/0/12939/88954e00-6ab5-8ae8-4bb9-9f206773edff.png)

コンソールアプリを選びます。

#### コーディングする

##### プログラムの概要

- コンソール上で文字列を入力すると、入力した文字列が出力されます
- 内部では、あらかじめmallocでヒープに100バイトの領域を確保し、入力された文字列をそこへ入れ、出力し、最後に解放します。

##### ソースコード

```cpp
#include "pch.h"
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <malloc.h>  // _msize()を使うのに必要

int main()
{
	char *str;

	/* 文字列のためのメモリを確保 */
	str = (char *)malloc(100);
	if (str == NULL) {
		printf("メモリが確保できません\n");
		exit(1);
	}

	/* 文字列を入力 */
	std::cin.getline(str, _msize(str));
	//std::cin.getline(str, sizeof(str));
	// こっちだと3文字しか表示されません
	// ポインタのサイズ（この場合は4バイト＝32ビット、つまり32ビット環境）
	// を返してしまっているからです
	// （最後の1バイトは終端文字に使われている）

	/* 文字列の表示 */
	puts(str);

	/* メモリの解放 */
	free(str);

	return 0;
}
```

なぜ`sizeof()`では駄目なのか？は以下のページでわかりやすく説明されています。

[せりか式 - C 言語チュートリアル - sizeof演算子](http://www.kis-lab.com/serikashiki/C/C03.html)

`malloc_usable_size()`が使えない理由はこちらです。

[\[故\]ぶろぐ: mallocで確保したサイズを後から取得する。](https://ko-burogu.blogspot.com/2014/08/malloc.html)

#### プログラムを実行する

![ConsoleApplication2 - Microsoft Visual Studio 2019-01-02 04.07.16.png](https://qiita-image-store.s3.amazonaws.com/0/12939/f4af59c6-e684-c435-bb6d-b64d95b5520a.png)

ブレークポイントを置いて、ローカルでバッグ実行します。

<img width="896" alt="2019年1月2日.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/12939/6fd21a11-fc9b-ab04-8a7a-29220332b630.png">

ステップ実行する前に、メモリウィンドウを開きます。

ステップ実行します。

![ConsoleApplication2 (Debugging) - Microsoft Visual Studio 2019-01-02 04.14.15.png](https://qiita-image-store.s3.amazonaws.com/0/12939/bb80ad41-b3d6-65fb-bbb2-0a2c89321a91.png)

mallocでヒープメモリに確保された領域の先頭のアドレスが出てきました。そこを見てみましょう

![ConsoleApplication2 (Debugging) - Microsoft Visual Studio 2019-01-02 04.16.51.png](https://qiita-image-store.s3.amazonaws.com/0/12939/c1fef6e9-d845-d6f8-ce1d-09ae8b772abd.png)

左上にアドレスを入力すると、ちょうど100バイト、メモリが確保されています。

![C__Users_uedat_source_repos_ConsoleApplication2_Debug_ConsoleApplication2.exe 2019-01-02 04.19.24.png](https://qiita-image-store.s3.amazonaws.com/0/12939/c8c20d92-8520-4f4c-fa34-4cb8e6418e24.png)

コンソールが起ち上がるので、好きな文字列を入れてEnterしましょう。

![ConsoleApplication2 (Debugging) - Microsoft Visual Studio 2019-01-02 04.21.02.png](https://qiita-image-store.s3.amazonaws.com/0/12939/54bd332d-4dd1-6878-e325-6e8ac1ab283f.png)

おお、入っています。

![C__Users_uedat_source_repos_ConsoleApplication2_Debug_ConsoleApplication2.exe 2019-01-02 04.22.10.png](https://qiita-image-store.s3.amazonaws.com/0/12939/830f0182-505f-535e-6e22-9eadd42f3911.png)

コンソールにも出力されました。

![ConsoleApplication2 (Debugging) - Microsoft Visual Studio 2019-01-02 04.23.07.png](https://qiita-image-store.s3.amazonaws.com/0/12939/c9c629e2-39f9-0fa2-807d-643173f3b384.png)

メモリが解放されました。

### 考察

Visual Studioってすごいんですね（疲れている）。

### おまけ

[The Weight of the World \- YouTube](https://www.youtube.com/watch?v=Egn_VNVKzI4)