2017-11-08 9 views
1
int main() 
{ 
    char *s; 
    strcpy(s,"here"); 
    return 0; 
    } 

上記のコードでは、文字列リテラルのメモリはグローバルスペースに割り当てられていると思われます。コンパイラは、プログラム空間でそれを割り当てて割り当てますか?また、同じ文字列リテラル、つまり(char *k = "here";)で別の文字列を初期化すると、同じメモリ位置を指します。 私はこの場所を解放することができないので、私は自分のコードに文字列の初期化がたくさんあると問題に遭遇すると思います。私は、この場合、ランタイムメモリの割り当てがないので、コンパイラの出力が大きすぎることを心配する必要があるのは唯一のことだと思いますか?文字列リテラルstrcpyのメモリ割り当て

+3

リテラルが 'に割り当てられています。ロナタ。または、短い文字列であり、レジスタに収まるので、割り当てられないことさえあります。しかし、あなたのコードは、とにかく無効です。 's'は全く割り当てられていないからです。 –

答えて

3

正確な場所は、オブジェクトファイル形式(PEELFCOFF)とコマンドラインオプション(文字列リテラルを書き込み可能なメモリセグメントに格納できるものもあります)によって異なります。 ELFはそれを.rodataセグメントに格納します。このセグメントは、その名前が示すように、読み取り専用です。

同じ文字列リテラルの複数のインスタンス同じ場所にマップしますが、必須ではありませんAFAIK(私は同じリテラルの複数のインスタンスを作成するコンパイラは認識していませんが、私の経験はそうではありません広い)。

特定されているもの:

  • プログラムが終了するまで、文字列リテラルのためのスペースは、プログラムの起動時に割り当てられた(通常はプログラムがメモリにロードされたとき)と開催されます。
  • 文字列リテラル呼び出す未定義の動作の内容を変更しようとすると - あなたのコードはセグメンテーション違反したり、意図した通りに動作すること、またはそれはあなたのハードドライブを再フォーマットしたり、それがゾンビの黙示録をトリガすることができます。あなたのコードにバグがあり

注 - sに意味のあるアドレスを割り当てることはありませんので、strcpyは、本質的に再び未定義の動作でランダムな位置に文字列"here"を書き込もうとしています。

sにリテラルを指すように設定している可能性があります。そうでない場合には、sは、文字列を保持するのに十分な大きさの配列である必要はあります次のいずれか

char s[sizeof "here"]; // sizeof evaluated at compile time 

か、動的に領域を割り当てる必要があります:

char *s = malloc(strlen("here") + 1); 
if (s) 
    strcpy(s, "here"); 
関連する問題