アプリ版:「スタンプのみでお礼する」機能のリリースについて

非常に基礎的な質問なのですが、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";」は全然意味が違う、というのはわかります。

A 回答 (2件)

文字列リテラル…なので、プロセス終了までメモリ上にあるかと思われます。


# DLLとかで動的にロード、アンロードした場合はその限りではないでしょうけど。

同じ文字列を別々の関数で…という場合に同じアドレスになるかは環境次第かもしれません。
# 最適化の状況にもよる。かと。
    • good
    • 0
この回答へのお礼

ありがとうございます。

>文字列リテラル…なので、プロセス終了までメモリ上にあるかと思われます。

なるほど、こういうのを文字列リテラルというのですね。
用途としては、静的なログメッセージや静的な定型文を返すのに利用できないものかと考えていました。ずっと使えるということは、reentrantというべきかthread safeというべきかわかりませんが、マルチスレッドプログラミングにおいても問題なく使えそう、ということですね。

>同じ文字列を別々の関数で…という場合に同じアドレスになるかは環境次第かもしれません。
># 最適化の状況にもよる。かと。

これができるなら、すごいですね。たとえマクロで書いたとしても、プリプロセッサで単なる文字列にばらされてしまうでしょうし。

お礼日時:2018/02/24 17:23

C 言語の立場では "こんなやつ" を「文字列リテラル」と呼びます (「文字列」はライブラリの仕様に出てくるけど言語そのものには出てこない). これは static storage duration の配列なので, プログラムの実行中はず~っとメモリ上にあります (仮想メモリ的には).



そして文字列リテラルがアドレスを共有するかについては規格上「そういうこともあるかもしれない」となっているので, 複数の文字列リテラルが同じ領域を共有するかもしれないし, それぞれ個別にあるかもしれません (「同じ関数の中にあれば共有する」とか「同じソースファイルであれば共有する」でも可). プログラムにはどちらでも問題ないことが求められます.

なお, printf("%s%s\n", ...) と printf("%s\n", ...) がある場合に, 2つの文字列リテラル ("%s%s\n" と "%s\n") を 1つにまとめているかもしれません.
    • good
    • 0
この回答へのお礼

ありがとうございます。

>なお, printf("%s%s\n", ...) と printf("%s\n", ...) がある場合に, 2つの文字列リテラル ("%s%s\n" と "%s\n") を 1つにまとめているかもしれません.

おー、fmtの文字列も文字列リテラルなのですね。
確かに、実行バイナリをstringsコマンドで見ると、フォーマット文字列も大量に出てきます。sort | uniq -c してみると、結構全く同じ文字列が複数含まれているようですが、真面目に数えてみるといくつかはアドレスを共有しているのかもしれませんね。

お礼日時:2018/02/25 01:32

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!