4

期待どおりに機能するファイル書き込みコードがいくつかありますが、デバッグモードではエラーが出力され、リリースでは出力エラーが出力されません。

コード:

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>

using namespace std;

int main (int argc, char * const argv[]) {
    string cppfilename; 
    std::cout << "Please enter the filename to create: ";

    while ( cppfilename == "" ) {
        getline(cin, cppfilename);    // error occurs here
    }

    cppfilename += ".txt";
    ofstream fileout;
    fileout.open( cppfilename.c_str() );
    fileout << "Writing this to a file.\n"; 
    fileout.close();

    return 0;
}

デバッグ出力:

Please enter the filename to create: Running…
myfile
FileIO(5403) malloc: *** error for object 0xb3e8: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Created: myfile.txt

リリース出力:

FileIO implementation C++
Please enter the filename to create: Running…
myfile
Created: myfile.txt

(簡単にするために)ファイル記述子が開いていることをチェックしないことを除いて、このコードの何が問題になっていますか?

更新:コードを次のように分解しましたが、それでもエラーが発生します:

 string cppfilename; 
 getline(cin, cppfilename);    // error here
4

2 に答える 2

6

libstdc++これは、少なくともデバッグ モードでコンパイルされた場合、Apple の のバグのように見えます。上記の 2 行の削減をコンパイルすると、次のようになります。

#include <iostream>
#include <string>

using namespace std;

int main() {
  string cppfilename; 
  getline(cin, cppfilename);    // error here

  return 0;
}

次のコマンド ラインを使用します (C++ プロジェクトでのデバッグ ビルドの Xcode の既定の設定から取得した定義を使用)。

g++ -D_GLIBCXX_DEBUG=1 -D_GLIBCXX_DEBUG_PEDANTIC=1 -g -o getline getline.cpp

次に、あなたが見たのと同じエラーが表示されます。

$ ./getline foo
getline(74318) malloc: *** error for object 0x1000021e0: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap

これにより、クラッシュ レポートがポップアップ表示され、スタック トレースが得られます (これを Xcode で実行することにより、デバッガーからスタック トレースを取得することもできます。原因を特定するために、できるだけクリーンな環境で再現したかっただけです)。 、他に奇妙なXcodeが行っている可能性のあるものは何もありません):

Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
0   libSystem.B.dylib               0x00007fff83c37fe6 __kill + 10
1   libSystem.B.dylib               0x00007fff83cd8e32 abort + 83
2   libSystem.B.dylib               0x00007fff83bf0155 free + 128
3   libstdc++.6.dylib               0x00007fff813e01e8 std::string::reserve(unsigned long) + 90
4   libstdc++.6.dylib               0x00007fff813e0243 std::string::push_back(char) + 63
5   libstdc++.6.dylib               0x00007fff813c92b5 std::basic_istream<char, std::char_traits<char> >& std::getline<char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char) + 277
6   getline                         0x00000001000011f5 std::basic_istream<char, std::char_traits<char> >& std::getline<char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) + 64 (basic_string.h:2451)
7   getline                         0x0000000100000cbf main + 34 (getline.cpp:10)
8   getline                         0x0000000100000c04 start + 52

これは私には非常にバグのように見えます。いくつかの標準ライブラリ関数を可能な限り簡単な方法で使用しており、アサーション エラーが発生しています。

この時点で、プロプライエタリ ソフトウェア (Apple のソフトウェアの多くlibstdc++はフリー ソフトウェアですが、幸運にもフリー ソフトウェアです) を使用している場合は、あきらめて、ベンダーにバグ レポートを提出し、回避策を見つける必要があります。幸いなことに、これはフリー ソフトウェアであるため、根本的な原因を調査できます。残念ながら、現時点ではこれを根本原因まで追跡する時間はありませんが、ソースは閲覧可能です。

おそらく、これについてバグを報告する必要があります。この場合の回避策は、_GLIBCXX_DEBUG=1 定義 (およびおそらく _GLIBCXX_DEBUG_PEDANTIC=1 も) を削除することです。Xcode でこれを行うには、ターゲットを見つけ、ビルドする実行可能ファイルをダブルクリックし、[ビルド] タブに移動して、構成が [デバッグ] に設定されていることを確認し、[ GCC 4.2 - 前処理]セクションまで下にスクロールして、2 つの値を削除します。Preprocessor Macros行。この方法でコードがビルドおよび実行され、この場合は機能しているように見えますが、標準ライブラリのデバッグ ビルドがキャッチできた可能性のあるアサーションは少なくなります。

于 2009-12-26T08:39:44.873 に答える
5

これは、Mac OS X の gcc 4.2 で _GLIBCXX_DEBUG が壊れている別のケースのようです。

最善の選択肢は、_GLIBCXX_DEBUG を削除するか、gcc 4.0 に切り替えることです。

于 2009-12-26T08:38:04.127 に答える