• ベストアンサー

stringについて

確認したいのですが、ある関数の引数はconst string& strでやる場合 文字列リテラルは、ヒープが確保してそれをポインタであるstringに渡される。だからコピーされる手間が減るとういことでよろしいのでしょうか? 環境はvisual C++ 2005です。

  • 79562
  • お礼率68% (164/239)

質問者が選んだベストアンサー

  • ベストアンサー
  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.3

> 何と比較するのかというとstring str です。 「const string &str」と「const string str」の違いについては、 &付き(参照渡し)の場合は、string オブジェクトへのポインタが関数に渡されるため、オブジェクトのコピーは発生しません。 &無し(値渡し)の場合は、string オブジェクトの複製が作られるため、そこでオーバーヘッドが発生します。 オブジェクトを複製する際に、どういうオーバーヘッドが発生するのかは実装依存です。 文字列の実データはオブジェクト毎にヒープを確保するような実装であれば、オブジェクトの複製時に、ヒープなどへのメモリ確保とコピーが行われますが、 参照カウンタを用いた実装であれば、文字列の実データそのもののコピーは行われません。(それでも、オブジェクトの複製処理のオーバーヘッドはある程度発生しますので、参照渡しの方がオーバーヘッドは少ないでしょう) const の有無については、今回の話の大筋には関係ありません。 「const string &str」と「string &str」の違いであれば、メモリ確保などの基本的な取り扱いは同じです。 ですが、constが付いている=書き換えられる心配がない、ということから、より最適化されて、もしかしたらコピーが減るかもしれません。 > あとこういうのは、stringに限ったことなのでしょうか? 上述の通り、参照渡しでオーバーヘッドが減るのは、string に限った話ではありません。 オブジェクト一般について「参照渡しにした方がオーバーヘッドは少ない」と言えます。

79562
質問者

お礼

なるほど。わかりました。ポインターが関数に渡されてオブジェクトのコピーはしないのですね。回答ありがとうございました。

その他の回答 (2)

  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.2

質問「constについて」の時の回答にもありましたけど、 「const string& str」と「何」とを比較するのかが言及されていませんので、 「コピーされる手間が減るのか」と聞かれても答えようがありません。 あとは、実装依存の話ですが、 多くの実装では、string の実データはヒープ上に確保するようになってますが、 VC++では、15文字以下の場合、ヒープを使わないようになってるらしいです。 http://d.hatena.ne.jp/AMENOHI/20090207 この場合、自動変数などスタック上に確保したstring型オブジェクトなら、 15文字以下なら文字列データも一緒にスタック上にあることになります。

79562
質問者

お礼

回答ありがとうございます。そうだったのですか。15文字以下はヒープを使っているのですね。何と比較するのかというとstring str です。

79562
質問者

補足

あとこういうのは、stringに限ったことなのでしょうか?

  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

strを文字列リテラルで初期化したということでしょうか(string str = "ABC";) 文字列リテラル(上の"ABC")はヒープには無いでしょう strには文字列リテラルをコピーした文字列があるでしょうがそれがスタックかヒープかはわかりません。

79562
質問者

お礼

回答ありがとうございます。初期化ではなく仮引数にした場合です。

関連するQ&A

  • java String[]

    メソッドを作成します 引数で String[] をもらいその個数を調べます その個数分の String[] を確保して 操作した文字列をセットして String[] の先頭ポインタをreturn します String[] の個数を調べる方法と その数だけ配列の確保の方法 を調べていますがよく分かりません よろしくお願いします

  • c++のstd::stringについて

    VC++2008でフォームアプリケーションを作成しています。 シリアルポートから受け取った文字列の一部を抜き出して処理をするため,VBではmid関数に相当するような機能として,std::stringを使用しようとしています。 しかし, std::string str("ABC" ,1,2); とした場合は『BC』が問題なく返ってきましたが, std::string str(recieveddata ,1,2); のように,文字列の部分を変数にしたら,ビルドエラーになってしまいます。(ポインタ?を理解する必要があるのでしょうか?) どのようにすれば,VBのmid相当の機能を実現できるでしょうか?

  • char型とstring型について

    char型とstring型について質問があります。 言語はC++です。 以下の関数があったとします。 void test(string a, string b string c){ 処理 } この関数を下記のように利用した場合について質問があります。 a.引数に直接文字列を挿入したケース test("aaa","bbb","ccc") b.変数に文字列を設定し、変数を引数にしたケース string a="aaa" string b="bbb" string c="ccc" test(a,b,c) (1)はコンパイルエラーになり、(2)は成功しました。 同じ様に見えるのですが、何が違うのでしょうか? また、関数の引数の型をchar*にした場合、(1)(2)のケースでコンパイルが通りました。char*型だと何が違うのでしょうか?

  • 関数の引数

    こんにちわ。 ご存知の方、ご教授してもらえないでしょうか? VB.net2005を使っているのですが 関数の引数に変数をセットして、別関数で 引数に対してデータをセットすることは可能でしょうか? C言語でいうところのポインタを引数に渡し ポインタアドレスに書き込むような処理はVB.netでは 可能なんでしょうか? 下記のような事は試したのですが、うまく出来ませんでした(。。; public sub test1() dim mojiretu as string test2( mojiretu ) msgbox(mojiretu) end sub public sub test2( str as string) str = "文字列" end sub

  • 分からないです(;_;)

    分からないです(;_;) 2 ユーザ関数char *my_strstr(const char *str1, const char *str2)とchar *strrep(char *src, const char *sch, const char *rep)を作成する。以下にユーザ関数の詳細を示す。 ・char *my_strstr(const char *str1, const char *str2) 文字列str1の中に文字列str2が含まれているか検索して、もし含まれているならばその位置をポインタで返し、含まれていないならばNULLを返す。ただし、以下の条件をつける。 ・文字列str2が文字列str1に複数含まれている場合は、str1の先頭から見て最初に現れるstr2を返す ・標準ライブラリ関数strcmp, strstrは使わない ・char *strrep(char *s, const char *sch, const char *rep) ユーザ関数my_strstrを用いて、文字列sの中に文字列schが含まれているか検索して、もし含まれているならばその部分を文字列repで置換し、置換した文字列の次の文字の位置を返す。含まれていないならばNULLを返す。ただし、以下の条件をつける。 ・文字列schが文字列sに複数含まれている場合は、sの先頭から見て最初に現れるschを置換する。 そして、キーボードから「文字列」「検索する文字列」「置換する文字列」を入力し、ユーザ関数strrepを用いて、「文字列」の中に含まれているすべての「検索する文字列」を「置換する文字列」で置換した結果と、「検索する文字列」が含まれていた個数を表示する。 <実行結果> Input a character string :anpanman Input a character string which you want to search :an Input a character string which you want to replace :enki The character string after replace is "enkipenkimenki" count :3 Input a character string :Yamanote-Line Input a character string which you want to search :Yamanote Input a character string which you want to replace :Chuo The character string after replace is "Chuo-Line" count :1 Input a character string :abc123/.@ Input a character string which you want to search :def Input a character string which you want to replace :xyz The character string after replace is "abc123/.@" count :0

  • std::stringクラスのc_str()で取得した文字列をいじることは可能ですか?

    c++で、以下のようなコードは問題ないでしょうか? // chrの中身の小文字を大文字にする void func(char* chr); std::string str("aaa"); const char* str_p = std.c_str(); func((char*)str_p); ←これは大丈夫ですか? //このあとstrに対して文字列を追加したりいろいろ処理する。 このようにc_strで取得したconst char*をconstをはずして 強引にいじくることは問題ないでしょうか?

  • C言語:小文字を大文字に変換する関数を作成

    C言語超初心者です。学校の課題で次のような問題が出されました。 ・問題・ 次に挙げる縛りに沿い、以下の関数とメイン関数を作り、処理結果を画面に作成しなさい。 char *tst(char *str) ・strの中の文字列も小文字を大文字に変換し、変換した文字列が格納されているchar *に返す。 ・引数strの中の文字列は受け取った状態で手を加えない。 ・関数内でmalloc関数を使用し、領域を確保して大文字に変換した文字列を格納しreturnでポインタを返す。 ・malloc関数を使用する。 ---------------------------------------------------------------------------------- 大文字に変換するには while(*str != '\0') { if(*str >= 'a' && *str <= 'z') { *str -= 'a'- 'A'; } ++str; } というのは分かったのですがここから何をすするか全く分かりません。初心者なのでなるべく分かりやすく教えてもらえると有難いです。 お願いします。

  • 「名前付き引数 string」とはどういう意味です

    Left 関数のヘルプを見ると、 ----------------------------------- 指定項目 :string 内容:必ず指定します。 この文字列式の左端から文字列が取り出されます。 名前付き引数 string に Null 値が含まれている場合は、Null 値を返します。 ----------------------------------- とヘルプに書かれてるのですが 「名前付き引数 string」とはどういう意味でしょうか? 「引数」と、「名前付き引数」は、別の物ですか? http://officetanaka.net/excel/vba/error/compilation_error/error_21.htm を見るところによると、 Replace 関数で例えるなら、 Cells.Replace What:="aaa", Replacement:="" の 「What:=」や「Replacement:=」の事を名前付き引数と言うで、あってますか? しかし、Left 関数には、「What:=」のような引数はないので、 名前付き引数は使われてないと思うのですが・・・ http://www.sanynet.ne.jp/~awa/excelvba/kouza/chapt_03/003.html を見たのですが、よくわかりませんでした。

  • System::String->char*変換でき

    C++/CLIでSystem::String^文字列をchar*に変換する関数を書いたのですが、256文字以上の文字列を投げて、戻値を確認してみると、255文字分しか中身が詰まっていません。元の文字列はアスキーのみです。 #include <msclr/marshal.h> using namespace msclr::interop; static char* toPtChar(const String^ Text) { String^ temp = (String^)Text; msclr::interop::marshal_context^ context = gcnew msclr::interop::marshal_context(); char* res = ((char*)(context->marshal_as<const char*>(temp))); return res; } この関数をどのように変更すれば、256文字以上変換できるでしょうか?

  • C/C++関数間でのStringクラスの扱い

    以下のようなコードを実行してみましたが思い通りに動いてくれません. "sample"という文字列がstrへとコピーされると思ったのですが. stringクラスのc_str()メソッドはconst char*だと言っているので無理矢理キャストしたのが原因でしょうか.stringクラスは記憶領域を自動で変更してくれるのではないのですか.それともこの挙動は仕様ですか. -------- 以下コード -------- #include <iostream> #include <string> using namespace std; int func(char *); int main(void) {     string str("");     func((char *)str.c_str());     cout << "String: " << str << endl;     return EXIT_SUCCESS; } int func(char *buf) {     buf = "sample";     return 0; } -------- 以上コード --------

専門家に質問してみよう