std::stringをバッファとして使用することのデメリットはありますか?
2023-12-21 02:32:28
質問
最近、私の同僚が
std::string
をバッファとして使っているのを見ました。
std::string receive_data(const Receiver& receiver) {
std::string buff;
int size = receiver.size();
if (size > 0) {
buff.resize(size);
const char* dst_ptr = buff.data();
const char* src_ptr = receiver.data();
memcpy((char*) dst_ptr, src_ptr, size);
}
return buff;
}
この人は、返された文字列の自動破壊を利用したいのでしょう。そうすれば、割り当てられたバッファの解放を心配する必要がありません。
これはちょっと
奇妙な
によると
cplusplus.com
は
data()
メソッドは
const char*
は文字列が内部で管理するバッファを指します。
const char* data() const noexcept;
const char ポインタへの Memcpy-ing ? AFAIKは、私たちが何をするか知っている限り、これは害を及ぼさないが、私は何かを見逃していますか?これは危険ですか?
どのように解決するのですか?
を使用しないでください。
std::string
をバッファとして使用しないでください。
を使用するのはバッドプラクティスです。
std::string
をバッファとして使用するのは、いくつかの理由(順不同)があります。
-
std::string
はバッファとしての使用を意図したものではありません。クラスの説明を再確認して、特定の使用パターンを妨げる (または未定義の動作を引き起こす) ような "gotchas" がないことを確認する必要があります。 -
具体的な例として。C++17 以前、あなたは
を書くことさえできません。
で得られるポインタを通して
data()
- で得られるポインタを介してconst Tchar *
であるため、あなたのコードは未定義の動作を引き起こすでしょう。(しかし&(str[0])
,&(str.front())
または&(*(str.begin()))
が使えるでしょう)。 -
使用する
std::string
をバッファに使うのは、関数の定義を読む人を混乱させます。std::string
を使っているのだろうと考えるからです。言い換えれば、そうすることで 最小驚嘆の原則 . - さらに悪いことに、次のような人は混乱することになります。 を使う 彼らは、あなたが返しているものが文字列、すなわち人間が読める有効なテキストであると考えるかもしれません。
-
std::unique_ptr
は、あなたのケースに適していますし、あるいはstd::vector
. C++17ではstd::byte
を要素の型に使用することもできます。より洗練されたオプションとして、クラスで SSO -のような機能、例えば Boost のsmall_vector
のようなものです (言及してくれた @gast128 さん、ありがとうございます)。 -
(細かい点ですが) libstdc++ は、その ABI を
std::string
の ABI を C++11 標準に準拠するように変更したため、場合によっては (今ではほとんどないでしょうが)、リンクや実行時に 問題 が発生する可能性があります。
また、あなたのコードはヒープ割り当てを1回ではなく2回行うかもしれません(実装に依存します)。文字列の構築時に一度、そして
resize()
のときです。しかし、それ自体が
std::string
の構造を使って二重の割り当てを避けることができるからです。
Jarod42 さんの回答
.
関連
-
[解決済み】浮動小数点例外エラーが発生する: 8
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み】標準ライブラリにstd::endlに相当するタブはあるか?
-
[解決済み】'std::cout'への未定義の参照
-
[解決済み] std::string を const char* または char* に変換する方法
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] std::stringのインスタンスを小文字に変換する方法
-
[解決済み] const std::string & をパラメータとして渡す時代は終わったのでしょうか?
-
[解決済み] sprintfのようなstd::stringの書式設定
-
[解決済み】char*をstd::stringに変換する。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】LLVMで暗黙のうちに削除されたコピーコンストラクタの呼び出し
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】デバッグアサーションに失敗しました。C++のベクトル添え字が範囲外
-
[解決済み] [Solved] インクルードファイルが開けません。'stdio.h' - Visual Studio Community 2017 - C++ Error
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)
-
[解決済み] 警告:暗黙の定数変換でのオーバーフロー
-
[解決済み] std::stringの文脈における頭文字SSOの意味