非常に基礎的な質問なのですが、C言語の関数内で「const char *hoge = "hoge";」のように宣言、初期化したポインタの先の文字列って永遠に消えない場所に格納されている(いつでも参照可能)なのでしょうか?
過去の質問を漁ってみたら、次のようなものがありました。ちょっと難しい言葉がたくさん出てきているのですが、私なりの理解では、永遠に消えない場所に格納されていていつでも参照可能なのかなと思っています。
https://oshiete.goo.ne.jp/qa/4904618.html
たとえば、次のようなコードでは、get_hoge()の中でconst char *hogeとして宣言しているポインタの先にある"hoge"という文字列は、たとえget_hoge()に書かれているhogeというポインタがスタックから消え去った後でもプログラムが終了するまで消えないものなのかどうか、ということです。POSIX threadでプログラムを書いているのですが、いろいろなところでget_hoge()が呼び出されても、ある呼び出しで返されたポインタの先の中身は保証されるものなのかどうかが知りたいです。
#include <stdio.h>
const char *
get_hoge() {
const char *hoge = "hoge";
return hoge;
}
int
main() {
const char *hoge;
hoge = get_hoge();
printf("%s\n", hoge);
return 0;
}
ちなみに、「const char hoge[] = "hoge";」は全然意味が違う、というのはわかります。
No.1ベストアンサー
- 回答日時:
文字列リテラル…なので、プロセス終了までメモリ上にあるかと思われます。
# DLLとかで動的にロード、アンロードした場合はその限りではないでしょうけど。
同じ文字列を別々の関数で…という場合に同じアドレスになるかは環境次第かもしれません。
# 最適化の状況にもよる。かと。
ありがとうございます。
>文字列リテラル…なので、プロセス終了までメモリ上にあるかと思われます。
なるほど、こういうのを文字列リテラルというのですね。
用途としては、静的なログメッセージや静的な定型文を返すのに利用できないものかと考えていました。ずっと使えるということは、reentrantというべきかthread safeというべきかわかりませんが、マルチスレッドプログラミングにおいても問題なく使えそう、ということですね。
>同じ文字列を別々の関数で…という場合に同じアドレスになるかは環境次第かもしれません。
># 最適化の状況にもよる。かと。
これができるなら、すごいですね。たとえマクロで書いたとしても、プリプロセッサで単なる文字列にばらされてしまうでしょうし。
No.2
- 回答日時:
C 言語の立場では "こんなやつ" を「文字列リテラル」と呼びます (「文字列」はライブラリの仕様に出てくるけど言語そのものには出てこない). これは static storage duration の配列なので, プログラムの実行中はず~っとメモリ上にあります (仮想メモリ的には).
そして文字列リテラルがアドレスを共有するかについては規格上「そういうこともあるかもしれない」となっているので, 複数の文字列リテラルが同じ領域を共有するかもしれないし, それぞれ個別にあるかもしれません (「同じ関数の中にあれば共有する」とか「同じソースファイルであれば共有する」でも可). プログラムにはどちらでも問題ないことが求められます.
なお, printf("%s%s\n", ...) と printf("%s\n", ...) がある場合に, 2つの文字列リテラル ("%s%s\n" と "%s\n") を 1つにまとめているかもしれません.
ありがとうございます。
>なお, printf("%s%s\n", ...) と printf("%s\n", ...) がある場合に, 2つの文字列リテラル ("%s%s\n" と "%s\n") を 1つにまとめているかもしれません.
おー、fmtの文字列も文字列リテラルなのですね。
確かに、実行バイナリをstringsコマンドで見ると、フォーマット文字列も大量に出てきます。sort | uniq -c してみると、結構全く同じ文字列が複数含まれているようですが、真面目に数えてみるといくつかはアドレスを共有しているのかもしれませんね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングのペーパーテスト 実行結果を表示せよ #include <stdio.h> int h 1 2022/07/09 15:27
- JavaScript javascriptで文字分割は、 split() などメソッド不要??? 4 2023/02/06 22:50
- HTML・CSS 全部のアクセスを指定したページに転送させたい 2 2022/06/28 16:33
- XML XML同じ名前の要素を自動で集約するツール 1 2022/04/11 09:21
- Windows 10 バッチファイルの記述法とルールについてアドバイスをお願いいたします。 1 2022/04/13 10:50
- C言語・C++・C# プログラミングのペーパーテスト 実行結果がどのように表示されるか答えよ #include <stdi 1 2022/07/09 14:27
- JavaScript JavaScriptで「〇以上▲まで」の書き方 1 2022/07/20 14:44
- C言語・C++・C# sprintf()の使い方について 1 2022/08/17 16:16
- PostgreSQL 【PostgreSQL】行の値の並びを変えるには 1 2023/03/21 16:46
- JavaScript ifreamをリロードしたい 1 2022/05/03 16:15
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
URLの一部をコピーできるブック...
-
c++プログラム。どこがだめか教...
-
HTTPSのとき":"が"%3A"ではなく...
-
functionから別のfunctionを実...
-
javascriptで自動計算フォーム...
-
日本語入力の禁止
-
関数でy=g(x)のgとは何の略です...
-
google apps scriptの終了のさせ方
-
空の配列に2次元配列の追加
-
第3日曜日のみの日付を取得、...
-
HTML:Tableタグに対し、JavaScr...
-
React hooksが値を返して配列変...
-
javaScript textareaの一行あた...
-
Javascriptで引数の参照渡しか...
-
innerHTML実行後のイベント
-
ActiveXobjectが作成できない
-
リンクボタンからインラインフ...
-
別窓を開いて、ページ下部中央...
-
CDの曲をケータイのSDに移す
-
択一形式のテストをつくりたいです
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Boolean型配列中のTrueの有無を...
-
【正規表現】【javascript】CR...
-
ASP+アクセスでのSQLコメントに...
-
Linux バイナリ実行できない "...
-
Vb.netのグローバル変数の宣言...
-
ボタンをクリックすると数が増...
-
【Jquery】changeイベント毎にa...
-
正規表現で半角数字1桁のみを全...
-
「オブジェクトが必要です。」...
-
HTTPSのとき":"が"%3A"ではなく...
-
onclick指定関数の引数へローカ...
-
同じ型【ハイフンと数字】だけ...
-
Excel VBA の ChangeFileAccess
-
C# .NET DataGridView の行を追...
-
javascriptで文字挿入でtoggle...
-
ifreamをリロードしたい
-
window.onloadでのfunction
-
static constメンバ変数(配列)...
-
MFCのキャプション変更
-
アンカーリンクをクリックさせ...
おすすめ情報