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

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

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

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

C++

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

Q&A

解決済

2回答

290閲覧

メンバ変数にて配列の要素数が2以上で確保できない

Sado

総合スコア89

Visual Studio

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

C++

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

0グッド

0クリップ

投稿2019/04/18 09:37

演習課題を行う過程で、配列データを渡しソートして返すという処理を行うことになりました。
しかし、メンバの配列が要素数1になってしまいます。
以下にコンストラクタを利用してメンバに配列変数を確保するサンプルを作ってみました。
メンバ変数の方の配列の要素数が1になります。

関数側でも配列を確保したいのですが、どのように正せばいいのでしょうか。

C++

1//main.cpp 2#include<iostream> 3using namespace std; 4#define arraySizeof(array) sizeof(array)/sizeof(array[0]) 5 6class TestArray { 7public: 8 int *data; 9 TestArray(int n) { data = new int[n]; } 10 ~TestArray() { delete(data); } 11}; 12 13int main() { 14 int a[256]; 15 cout << "Array Size = " << arraySizeof(a) << endl; 16 17 TestArray instance(100); 18 cout << "Array Size = " << arraySizeof(instance.data) << endl; 19 20 getchar(); 21 return 0; 22}

試したこと

このサンプルの形を取る前は、関数メンバに引数で「ソート対象の配列ポインタ」を直接渡すように設計していました。
void sort(int* data)のように配列データを直接渡す方法です。
このときも関数側では要素数が1になり、しかしmain()内に戻ってくると要素数は宣言した数通りに戻っています。
関数内と呼び出し元main()内で、ポインターをcoutで表示させてみましたが、一致してしまいました。
nullptrや他の値にはなっていません。

先生の指摘により、メンバとコンストラクタを利用した形に書き換えてみましたが、状況は変わりませんでした。

補足情報

VS2015 , C++ , win32コンソールアプリ

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

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

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

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

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

guest

回答2

0

ポインタは、型とアドレスのみを保持し
指しているアドレスがどれだけの領域を確保しているかという情報を持ちません。

c++

1class TestArray { 2public: 3 int *data; 4 const int size; 5 TestArray(int n) : size(n) { 6 data = new int[n]; 7 } 8 ~TestArray() { delete[] data; } 9};

このようなものを作ることになりますが、既成品としてstd::vectorがありますので
そちらを用いるのが便利です。

c++

1#include <vector> 2#include <iostream> 3using namespace std; 4#define arraySizeof(array) sizeof(array)/sizeof(array[0]) 5 6int main() { 7 int a[256]; 8 cout << "Array Size = " << arraySizeof(a) << endl; 9 10 vector<int> instance(1000); 11 cout << "Array Size = " << instance.size() << endl; 12 13 getchar(); 14 return 0; 15}

#define arraySizeof(array) sizeof(array)/sizeof(array[0])
VS2015ならばstd::sizeが使えますので
そちらを使うとよいでしょう。

c++

1int main() { 2 int a[256]; 3 cout << "Array Size = " << size(a) << endl; 4 5 vector<int> instance(1000); 6 cout << "Array Size = " << size(instance) << endl; 7 8 getchar(); 9 return 0; 10}

投稿2019/04/18 10:32

編集2019/04/18 10:33
asm

総合スコア15147

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

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

Sado

2019/04/18 12:14

回答ありがとうございます。 サンプルも示していただいて、本当に助かります。 vectorの存在自体は知っていたのですが、生配列と比べて遅いと言われる点と、演習で「配列」を使用するという条件がありましたので、vector無しでどうにかできないものかと悩んでいました。 ポインタの理解が足らず、int a[N]した配列aの感覚で、ポインタのaが利用できるものとばかり誤解していたのが今回のミスの大元だったみたいです。 sizeofによる「ポインタ」を利用した計算が、失敗だったわけですね......。
asm

2019/04/18 13:13

> 生配列と比べて遅い 理想的なコンパイラを考えた場合、使い方を間違えない限り配列との速度差はありません。 アライメントが保証できますしポインタよりも高速になる可能性すらありえます。 (現実には、ベクトル演算がstd::venctorだとサポートされてなかったりしますが・・・ コンパイラの発展に期待ですね)
guest

0

ベストアンサー

要素数の計算方法を間違えているだけです。
sizeofでポインタ自体のサイズを取得してしまっています。

C++

1#include <iostream> 2 3int main(void) { 4 int arr1[10]; 5 int *p_arr1 = arr1; 6 7 int *p_arr2 = new int[10]; 8 9 std::printf( 10 " arr1: %2ld\n" 11 "p_arr1: %2ld\n" 12 "p_arr2: %2ld\n", sizeof(arr1), sizeof(p_arr1), sizeof(p_arr2) 13 ); 14 15 delete[] p_arr2; 16}

実行結果 Wandbox

arr1: 40 p_arr1: 8 p_arr2: 8

また new int[] で取得した領域は delete[] で解放してあげる必要があります。


配列の先頭ポインタから配列要素数を一般に計算する方法はありません。
C++ならば生配列ではなくstd::vectorを使えば良いでしょう。

void sort(int* data)のように配列データを直接渡す方法です。

このときも関数側では要素数が1になり、しかしmain()内に戻ってくると要素数は宣言した数通りに戻っています。

渡っているのは配列自体ではなく、配列の先頭アドレスだからです。
どうしても生配列を扱いたいのなら、要素数を併せて渡してやるのが定石です。

投稿2019/04/18 09:44

編集2019/04/18 10:36
LouiS0616

総合スコア35660

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

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

Sado

2019/04/18 12:08

回答ありがとうございます。 ポインタの理解が足りませんでした。 int a[N]で宣言したaと,ポインタのaを全く同一視してしまったことが間違いだったわけですね......。
Sado

2019/04/18 12:15

sizeofでうまく要素数が計算できない事について、納得しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問