2016-10-17 4 views
1
#include <iostream> 
#include <cstring> 
using namespace std; 
int main() 
{ 
    char str1[10] = "Hello"; 
    char str2[10] = "World"; 
    int len ; 
    strcat(str1, str2); 
    len = strlen(str1); 
    cout << len << endl<<str1<<endl; 
    return 0; 
} 

で異なっています。 strcatではstr1str2に連結し、最初の文字列のサイズは10で、文字列の長さも10です(余分なヌル文字を意味しません)。なぜこの変化する行動ですか? strcat機能でC文字列のC++文字列を変換していますか、説明してください。C++文字列の動作は定義ながらstrcatの目的球

+1

あなたはコンパイルエラーが出た場合、それはあなたがそうどのような方法でC++の文字列を使用していない – Hayt

+2

、あなたの質問にそれらを追加する場合は、必ずehlpfulです彼らはこれとは何の関係もありません。それ以外の場合、私はあなたが何を求めているのか本当にわからない。あなたは未定義の動作を呼び出すでしょう。 –

+1

[参照](http://en.cppreference.com/w/cpp/string/byte/strcat)を参照する必要があります。宛先が十分ではないので、未定義の動作があります。 – NathanOliver

答えて

2

は、我々は

いいえ、あなたのプログラムに関わる一切のC++の文字列(すなわちstd::string)が存在しない文字列C++を変換しています。

なぜこの変更された動作ですか?

あなたは別のプログラムを書きましたが、動作が異なります。

最初のケースでは、プログラムが不正な形式でした。標準では、コンパイル時にこれをコンパイラに通知する必要があります。あなたのバグを検出することはコンパイラにとっても簡単です。変数の型は "5文字の配列"です。 6文字は収まりません - タイプが間違っています。型はコンパイル時に知られています。


このコードでは、strcatを使用しています。あなたはthis referenceで見てみる場合は、コピー先の配列は、srcとdestのとヌル文字の両方の内容のために十分な大きさでない場合

行動が定義されていないことがわかります。

標準では、未定義の動作について警告するためにコンパイラを必要としません。実際には、コンパイラがプログラムに未定義の動作があることを証明することは、通常は非常に困難です。この特定のケースでは明らかです。

strcatの引数はポインタです。あなたは正しいタイプのポインタをstrcatに渡します。タイプエラーはありません。バグは間違った値になっています。値は実行時に配列にコピーされます(オプティマイザがいくつかの魔法をしない限り)。あなたのバグを理解するために、コンパイラはプログラムの実行をシミュレートする必要があります。すべてのコードパスでこれを行うのは非常に遅いでしょう。したがって、コンパイラは、strcatの前提条件を満たすためにプログラマに責任を委ねます。

0

これらはCスタイルの文字列であり、C++の文字列ではありません。つまり、std :: stringクラスを使用していません。 Cスタイルの文字列は '\ 0'で終わります。つまり、文字列の長さを超えて余分な格納場所が必要です。 "Hello"の長さは5ですが、格納するにはサイズ6の配列が必要です。あなたの例では、それだけで次の操作を行い、配列のサイズを指定すると、コンパイラがサイズを計算させるために、実際に必要はありません。

char str1[] = "Hello"; 

strcatの機能が必要とあり、配列の最初の引数のポイント連結された文字列のための十分なスペース。これは実際にそうであるかどうかをチェックしないので、危険な機能です。そうでなければ、配列の終わりを超えて上書きするだけです。あなたの場合、それぞれ5文字の長さの2つの文字列を連結すると、10文字の文字列が得られます。そして、最初の引数が11文字以上の配列を指していることを確認する必要があります。あなたがC++文字列を使用していた場合は、このいずれかを心配する必要はありません。

#include <string> 
#include <iostream> 

int main() 
{ 
    std::string str1("Hello"); 
    std::string str2("World"); 
    str1.append(str2); 
    std::cout << str1.size() << '\n' << str1 << std::endl; 
} 
関連する問題