問題の背景と該当のコード
C++でCSVファイルの各要素を配列に格納して返す関数を作っているのですが、バグを解決できず困っています。その関数はParseCSVToArray
という名前で、**「引数に既存のcsvファイル名(string型)を渡して、該当のcsvファイルの各要素に入っている非負整数の値をパースしてunsigned int**
型の配列にして返す」**というものです。
パース処理の便宜上、csvの中身はいったんvector<vector<int>
型の2次元配列arr2d
にパースして、その後にunsigned int**
型の2次元配列newarr
に入れなおしてnewarr
をreturnする、というやり方を取っています。
元のcsvファイルのデータのサイズは1025x1025です。
unsigned int** ParseCSVToArray(string filename) { ifstream csv_file; csv_file.open(filename); //csvファイルから値を読み取ってvector<vector<int>>型の2次元配列arr2dに格納 string line; vector<vector<int>> arr2d; while (getline(csv_file, line)) { string val; vector<int> row; stringstream s(line); while (getline(s, val, ',')) { row.push_back(stoi(val)); } arr2d.push_back(row); } csv_file.close(); //unsigned int**型の2次元配列newarrに変換 int sizeOfCSV = arr2d.size();//サイズは1025x1025 //デバッグ用のcout cout << "arr2d size:" << arr2d.size() << " arr2d.at(0).at(0)" << arr2d.at(0).at(0) <<endl; unsigned int** newarr = new unsigned int* [sizeOfCSV]; for (int k = 0; k < sizeOfCSV; ++k) { newarr[k] = new unsigned int[sizeOfCSV]; for (int i = 0; i < sizeOfCSV; ++i) { newarr[k][i] = arr2d.at(k).at(i); } } //デバッグ用のcout cout << "newarr size:" << sizeof(newarr) << " newarr[0][0]:" << newarr[0][0] << endl; return newarr; }
##問題点
ちゃんとcsvのファイルがarr2d
にパースされていること、それが適切にnewarr
に変換されていることを確かめるために、上記のデバッグ用のcoutを使って上の2つの2次元配列のサイズを調べてみました。
元のcsvファイルの2次元データのサイズは1025x1025です。
すると、arr2d.size()
の値は、正常に1025と出ました。しかし、sizeof(newarr)
の値は8でした。
これはarr2d
からnewarr
への変換作業の途中に間違いがあるのだと思います。
どこがおかしいのでしょうか?ご回答よろしくお願い致します。
##追記
質問文を書いている途中で気付いたのですが、arr2d
がint型のvectorにしているのに対して、newarr
はunsigned int型、と、型が違っていてまずいのではないかと思いました。この問題に直接関係あるかはわかりませんが、とりあえずvector<vector<int>>
からvector<vector<unsigned int>>
に変更してみようと思います。
##追追記
このサイトを見ると、「.size()によって返される値はint型ではなくsize_t型」ということを知ったので、上記のコードの一部を以下のように書き換えました。しかし、問題はそこではなかったようです。(依然としてsizeof(newarr)
の値は8のままです)
//unsigned int**型の2次元配列newarrに変換 size_t sizeOfCSV = arr2d.size();//サイズは1025x1025 //デバッグ用のcout cout << "arr2d size:" << arr2d.size() << " arr2d.at(0).at(0)" << arr2d.at(0).at(0) <<endl; unsigned int** newarr = new unsigned int* [sizeOfCSV]; for (size_t k = 0; k < sizeOfCSV; ++k) { newarr[k] = new unsigned int[sizeOfCSV]; for (size_t i = 0; i < sizeOfCSV; ++i) { newarr[k][i] = arr2d.at(k).at(i); } } //デバッグ用のcout cout << "newarr size:" << sizeof(newarr) << " newarr[0][0]:" << newarr[0][0] << endl; return newarr;
謎の挙動
また、試しに、sizeof(newarr)
の値である8を超える要素newarr[10][10]
を参照してみたところ、なぜか成功し、普通にcsvに書かれていた値を返しました。ただ、Visual Studioに以下の警告が出ました:
重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態 警告 C6385 'newarr' から無効なデータを読み取っています: 読み取り可能なサイズは 'sizeOfCSV*8' バイトですが、'88' バイトを読み取る可能性があります。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/03/29 08:03 編集