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

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

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

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

C++

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

Q&A

解決済

2回答

10752閲覧

std::copyを使用するとコンパイルエラーになる

JADEN

総合スコア106

Visual Studio

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

C++

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

0グッド

0クリップ

投稿2016/01/19 13:24

std::copyを使用するとコンパイルエラーになります。
何が原因なのか教えてください。
(書籍「ロベールのC++入門講座」p302のコードです)

コンパイラ: Visual studio community 2015
OS: Windows7 64 bit

エラーメッセージ
C4996 'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'

C++

1// CIntArray.h 2#ifndef C_INT_ARRAY_H 3#define C_INT_ARRAY_H 4 5class CIntArray { 6private: 7 int* array; 8 int arraySize; 9 10public: 11 CIntArray(int arraySize); 12 CIntArray(const CIntArray& intArray); 13 ~CIntArray(); 14 15 int Get(int index); 16 void Set(int index, int data); 17 int Size(); 18 19private: 20 void CheckIndex(int index); 21}; 22 23#endif

C++

1// CIntArray.cpp 2#include "CIntArray.h" 3#include <iostream> 4#include <cstdlib> 5#include <algorithm> 6 7CIntArray::CIntArray(int arraySize) { 8 array = new int[arraySize]; 9 this->arraySize = arraySize; 10 std::cout << "constructor: " << arraySize << std::endl; 11} 12 13CIntArray::CIntArray(const CIntArray& intArray) { 14 array = new int[intArray.arraySize]; 15 arraySize = intArray.arraySize; 16 std::copy(intArray.array, intArray.array + intArray.arraySize, array); 17 std::cout << "copy constructor" << std::endl; 18} 19 20CIntArray::~CIntArray() { 21 std::cout << "destructor: " << arraySize << std::endl; 22 delete[] array; 23} 24 25int CIntArray::Get(int index) { 26 CheckIndex(index); 27 return array[index]; 28} 29 30void CIntArray::Set(int index, int data) { 31 CheckIndex(index); 32 array[index] = data; 33} 34 35int CIntArray::Size() { 36 return this->arraySize; 37} 38 39void CIntArray::CheckIndex(int index) { 40 if (0 <= index && index < arraySize) { 41 // no process 42 } else { 43 std::cout << "インデックスが不正:" << index << std::endl; 44 exit(EXIT_FAILURE); 45 } 46}

C++

1// main.cpp 2#include "CIntArray.h" 3#include <iostream> 4 5void Show(CIntArray array) { 6 for (int i = 0; i < array.Size(); i++) { 7 std::cout << array.Get(i) << std::endl; 8 } 9} 10 11int main() { 12 CIntArray array0to9(10); 13 14 for (int i = 0; i < array0to9.Size(); i++) { 15 array0to9.Set(i, i); 16 } 17 18 Show(array0to9); 19}

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

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

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

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

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

guest

回答2

0

ベストアンサー

マイクロソフトは、メモリコピーなどでセキュリティ的に安全でない(バッファオーバーランなどを引き起こしやすい)使い方を、あえてできないようにしています。ご質問の件ではstd::copyにポインタを渡しているのが却下された理由です。STLコンテナのイテレーターなら問題ありません。

対処方法はChironianが書かれている通りです。


補足
エラーになるのはDebugビルドの時だけみたいですね。Releaseビルドではエラーにならずに通ってしまいました。

投稿2016/01/19 15:08

編集2016/01/19 15:13
catsforepaw

総合スコア5938

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

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

Chironian

2016/01/19 15:30

> std::copyにポインタを渡しているのが却下された理由です。STLコンテナのイテレーターなら問題ありません。 なるほど!! しかし、何故に手元のmsvc 2015で警告されないのか? 気になるので調べてみたら/Wオプションを指定しないと出ないようです。知らなかった。orz
catsforepaw

2016/01/19 15:41

> /Wオプションを指定しないと出ないようです。 もしかしてコマンドラインでコンパイルしてます? 私も知らなかった……。
Chironian

2016/01/19 16:17

小さなお試しソースをビルドする時はコマンドラインが多いのですよ。プロジェクト作るの面倒ですし。
JADEN

2016/01/20 10:54

回答ありがとうございました。
guest

0

こんにちは。

手元のVisual Studio Community 2013 update 5とVisual Studio Community 2015 update 1でコンパイルしてみましたが、警告もエラーもでませんでした。コマンドラインでコンパイルし/EHscオプション(例外関連の警告対策)しか付けてません。(無関係と思いますが、CIntArray.cppとmain.cppをまとめてます。)

JADENさんと同じ警告を報告している人がたくさんいますが、上の方から2~3見る限りVisual Studioのバージョンは古いようです。

C4996はメモリの不正アクセスするリスクがある時に出るもののようですが、普通に標準ライブラリを使っても出る警告なのでディセーブルすることも多いです。メッセージにあるように-D_SCL_SECURE_NO_WARNINGSオプションをつける、もしくは、#pragma warning(disable:4996)をソースの頭の方に書くことでこの警告を消すことができます。

JADENさんのmsvcで出て私のmsvcで出ないのはちょっと気になりますが...

投稿2016/01/19 14:55

Chironian

総合スコア23272

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

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

JADEN

2016/01/20 10:54

回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問