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

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

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

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

1回答

2431閲覧

ファイルマッピングについて

tmykbys

総合スコア14

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

1クリップ

投稿2020/09/24 18:11

編集2020/09/25 12:10

猫でもわかるC言語を履修中なのですが、
http://www.kumei.ne.jp/c_lang/intro2/no_114.htm
こちらのページの最下、サンプルプログラムをタグに示した環境でコピー・実行したところ、
l buffer is too small && 0
等のエラーが発生しました。

バッファが少なすぎるとのことなので増やしてみたりと試行錯誤を繰り返したのですが、
lpStr=NULLになったりととても初心者には分かりませんでした。

VisualStudioは最新版を使っており筆者様の環境と違って、セキュリティ的な面で様々な制約が発生しているからではないかと推測するのですが、どうすれば動くようになるのか教えていただけたら幸いです。

稚拙な説明で申し訳ございませんが、何卒よろしくお願いいたします。

◆追記

環境:Microsoft Visual Studio Community 2019 Version 16.7.2

エラーメッセージ:Bull様が提示してくださった通り、
Debug Assertion Failed!
Expression: (L"Buffer is too small" && 0)
と表示されます。

コード:dodox86様、Bull様のおっしゃる通り、
上記のコードを編集し、現在は以下の通りです。
scanf,gets等はscanf_s等、対応するものに書き換えました。

/* filemapping01.c */

#include <stdio.h>
#include <windows.h>
#include <conio.h>

int FRead(LPSTR);
int FWrite(LPSTR);

HANDLE hFMWrite;

int main()
{

static LPSTR lpAddress1, lpAddress2;

int szNo=0;
BOOL bEnd = FALSE;

while (1) {
printf("\n");
printf("1. Writre\n");
printf("2. Read\n");
printf("0. End\n");
printf("
\n");
printf("No. = ");
scanf_s("%d",&szNo);

switch (szNo) {
case 1:
FWrite(lpAddress1);
break;
case 2:
FRead(lpAddress2);
break;
case 0:
bEnd = TRUE;
break;
default:
printf("正しくない番号です\n\n");
break;
}
if (bEnd)
break;
}

if (hFMWrite) {
if (CloseHandle(hFMWrite) == 0)
printf("書き込みハンドルクローズ失敗\n");
else
printf("書き込みハンドルクローズ成功\n");
}

return 0;
}

int FWrite(LPSTR lpStr)
{
char szStr[1024];

if (!hFMWrite)
CloseHandle(hFMWrite);

hFMWrite = CreateFileMapping(
(HANDLE)-1,
NULL,
PAGE_READWRITE,
0,
1024,
"NEKODEMOWAKARU");
if (hFMWrite == NULL)
return -1;
if (GetLastError() == ERROR_ALREADY_EXISTS)
printf("すでにマッピングオブジェクトが存在しました\n");

lpStr = (LPSTR)MapViewOfFile(hFMWrite,
FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (lpStr == NULL)
return -2;

printf("書き込み==");
scanf_s(szStr,1024);
strcpy_s(lpStr,1024, szStr);
strcat_s(lpStr,1024, "\n");

UnmapViewOfFile(lpStr);

printf("書き込みました\n");
return 0;
}

int FRead(LPSTR lpStr)
{
HANDLE hFM;

hFM = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "NEKODEMOWAKARU");

lpStr = (LPSTR)MapViewOfFile(hFM,
FILE_MAP_ALL_ACCESS, 0, 0, 0);

if (lpStr == NULL) {
printf("受信失敗\n");
CloseHandle(hFM);
return -1;
}
printf(lpStr);
if (UnmapViewOfFile(lpStr) == 0) {
printf("読み込み用アドレスアンマップ失敗\n");
}
else {
printf("読み込み用アドレスアンマップ成功\n");
lpStr = NULL;
}

CloseHandle(hFM);

return 0;
}

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

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

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

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

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

y_waiwai

2020/09/24 21:53

コードを提示しましょう
DreamTheater

2020/09/24 22:43

実行時のエラー情報を具体的に記述してください。
dodox86

2020/09/24 23:15

タグで示したVisual Studioを使っている、とありますが、Visual Studioはたくさんのバージョンがあるので、お使いのバージョンを正確に示してください。(質問文中に追記してください) ご提示のサイトは生のWindows APIを使うサンプルで貴重な情報ではありますが、残念ながら古いものなので、gets()関数など、今では使うことができないものを利用しています。古いVisual Studio では利用できるかもしれませんが、それらの関数の実行でエラーが出ている可能性があります。どのようなパラメータを入力するとエラーが発生するかなど、詳細に手順を示してください。
dodox86

2020/09/24 23:54

なお、 > VisualStudioは最新版を使っており ご提示のサイトのコードそのままですと、最新版のひとつである「Microsoft Visual Studio Community 2019」ではgets()が使えない為、コンパイルエラーになります。
Bull

2020/09/25 06:25

エラーメッセージは Debug Assertion Failed! Expression: (L"Buffer is too small" && 0) でしょうか? もしそうであれば、参考サイトのソースから strcpy を strcpy_s に変更していますか? そして、どのように変更したのでしょうか?
tmykbys

2020/09/25 12:11 編集

皆様、情報不足により大変失礼いたしました。 早速追記いたしましたので、お目通しいただければ幸いです。 何卒よろしくお願い申し上げます。
guest

回答1

0

ベストアンサー

l buffer is too small && 0
等のエラーが発生しました。

エラー(実際にはAssertion)が発生するのは、修正の仕方が間違っているためです。発生しているのはFWrite関数の以下の部分です。

C

1printf("書き込み=="); 2scanf_s(szStr,1024); 3strcpy_s(lpStr,1024, szStr); 4strcat_s(lpStr,1024, "\n");

scanf、さらにそれを代替したscanf_sでは、書式制御文字列が必要です。この場合は簡単には"%s"を指定します。なぜ「l buffer is too small && 0」のエラーが発生するかと言えば、スタック領域であるszStrの配列の領域にはVisual Studio でのデバッグ実行時、0xccが埋め込まれる為です。これはデバッガー上で見ると"フフフフフ..."の文字列になります。(0xccはシフトJISで半角カタカナの'フ'です)

scanf_sでの引数指定が正しくされていないために、続くstrcpy_sで1024バイトを超えるコピーとなり、エラーになります。scanf_s(szStr,1024)の部分は、scanf_s("%s", szStr, 1024)のように書くのが正しいです。

尚、1024と直接にサイズを記載している部分は、より汎用的な_countofマクロ が使えます。これを適用して修正すると、以下のようになるでしょう。

C

1printf("書き込み=="); 2scanf_s("%s", szStr, _countof(szStr)); 3strcpy_s(lpStr, _countof(szStr), szStr); 4strcat_s(lpStr, _countof(szStr), "\n");

ついでに書けば、gets関数のより直接的な代替は fgets です。gets(szStr)は、fgets(szStr, _countof(szStr), stdin) と書き替えることができます。


余談:

本題とは関係ないですが、FWrite()関数の導入部、以下のコードは誤りだと思います。

C

1if (!hFMWrite) 2 CloseHandle(hFMWrite);

もともとhFMWriteのハンドルが開いていたら閉じる、を意図したコードだと思いますが、 CreateFileMapping で返される有効なハンドルの値はNULL以外なので、

C

1if (hFMWrite) /* if (hFMWrite != NULL) */ 2 CloseHandle(hFMWrite);

であるはずです。また、コードの冒頭部分でグローバル変数としてHANDLE hFMWrite;が宣言されていますが、自動的にNULLで初期化済みとは言え、

C

1HANDLE hFMWrite = NULL;

とでもしておいた方がまぁ分かり易いかもしれません。

投稿2020/09/25 18:38

dodox86

総合スコア9183

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問