2012-01-17 18 views
0

私はこれを安全に、効率的に、ほとんどの場合正しく実行していますか?カスタム文字列(C++ newbie)のデータを印刷するときに奇妙な出力が表示される

私は文字列クラスの実装を書くのに少し助けが必要です。おそらく誰かが私が知りたいと思うもので私を助けることができたでしょうか?

私は拡張機能と学習目的のために私自身の文字列クラスを作成しようとしています。私はこれをstd :: stringの代わりに使用しません。これは潜在的に危険な可能性があるためです。 :-P

私はstd :: coutを使用して文字列の内容を出力すると、予期せぬ出力が出て、なぜ私は思っているのですが、本当にわかりません。私は文字列内の文字を格納する他の方法はかなりうまく動作するので、私は割り当て関数に絞り込んだ。私が割り当てて保持するためのchar PTRのためにバイトの固定量を確保し、コンストラクタを持って

void String::assign(const String &s) 
{ 
    unsigned bytes = s.length() + 1; 

    // if there is enough unused space for this assignment 
    if (res_ >= bytes) 
    { 
     strncpy(data_, s.c_str(), s.length()); // use that space 
     res_ -= bytes; 
    } 
    else 
    { 
     // allocate enough space for this assignment 
     data_ = new char[bytes]; 
     strcpy(data_, s.c_str()); // copy over 
    } 

    len_ = s.length(); // optimize the length 
} 

:ここで私のアサイン機能です。それはそうのように宣言されています

explicit String(unsigned /*rbytes*/); 

res_変数は単にバイトと格納の量に渡された記録します。これはstring.cpp内のコンストラクタのコードです:

String::String(unsigned rbytes) 
{ 
    data_ = new char[rbytes]; 
    len_ = 0; 
    res_ = rbytes; 
} 

私はこの方法を使用すると、もう少し効率的ではなく、文字列のための新しい領域を割り当てるよりもだろうと思いました。だから私はちょうど私が新しい文字列を宣言したときに私は最初に予約された間隔を使用することができます。ここで私はそれが動作するかどうかを確認するためにテストしてい方法です:

#include <iostream> 

#include "./string.hpp" 

int main(int argc, char **argv) 
{ 
    winks::String s2(winks::String::to_string("hello")); 
    winks::String s(10); 

    std::cout << s2.c_str() << "\n" << std::endl; 

    std::cout << s.unused() << std::endl; 
    std::cout << s.c_str() << std::endl; 
    std::cout << s.length() << std::endl; 

    s.assign(winks::String::to_string("hello")); // Assign s to "hello". 

    std::cout << s.unused() << std::endl; 
    std::cout << s.c_str() << std::endl; 
    std::cout << s.length() << std::endl; 

    std::cout.flush(); 
    std::cin.ignore(); 

    return 0; 
} 

あなたがウインクを懸念している場合::文字列:: to_stringに、私は単にそのように私の文字列オブジェクトにchar型のPTRを変換しています:

String String::to_string(const char *c_s) 
{ 
    String temp = c_s; 
    return temp; 
} 

しかし、私はこのメソッドで使用するコンストラクタはプライベートなので、私は自分自身にto_stringを強制しています。これまでのところ問題はありませんでした。私は、これは異なるパラメータのための方法を書き換えないようにすることです作られた理由は、IEます。char *と文字列

プライベートコンストラクタのコード:

String::String(const char *c_s) 
{ 
    unsigned t_len = strlen(c_s); 
    data_ = new char[t_len + 1]; 
    len_ = t_len; 
    res_ = 0; 
    strcpy(data_, c_s); 
} 

をすべてのヘルプは大歓迎です。私は情報の効率的な量を提供していない場合は、あなたが知りたいと私に通知してくださいと私は喜んで私のポストを編集します。

編集:なぜ私は完全なstring.hppとstring.cppを投稿していないのですか?なぜなら、それはむしろ大規模であり、皆さんが望むかどうかわからないからです。

+1

'String :: assign'にメモリリークがあります。 – Mysticial

+0

どのように?私は割り当てのための十分な予約スペースがあるかどうか確認しています。私はそれが間違っている可能性があります。あなたは精緻化できますか? – john

+0

'else'部分では、既存の' data_'を削除する前に、その上に割り振ります。だからあなたは古い内容を漏らす。 – Mysticial

答えて

2

文字列を0で終端して常に保存するかどうかを決定する必要があります。文字列を終端ゼロバイトで保存しない場合、関数c_strを追加する必要があります。それ以外の場合は、C文字列を返しません。

assign機能は終了しません。だからそれは壊れているか、0で終了するつもりはありませんでした。前者の場合は修正してください。後者の場合は、c_str関数をチェックして最後に0を付けるようにしてください。

関連する問題