char * str = "Hello";
*(str+1) = '3';
cout<<str;
そこで私がやろうとしていたのは、2 番目の文字を「3」に変更して、H3llo に変えることでした。
うまくいかないのはなぜですか?
これは未定義の動作です。リテラルを変更することはできません。
リテラルへのポインタを取得するには、次のようにする必要があります。
const char* str = "Hello";
//^^^^^
次に、文字列を変更できるようにするには、これは、たとえば、
char str[] = "Hello";
もう1つのオプションは、メモリを動的に割り当てることです(malloc
とを使用free
)
文字列リテラルは読み取り専用メモリに割り当てられるため、基本的には型( const char *
)です。変更できません。詳しくはこちらもご覧ください。
str は「const char *」型であり、それが指すオブジェクトを上書きすることは許可されていないためです。
のメモリはセクションstr
で割り当てられ.rodata
ます。したがって、読み取り専用データを変更しようとすると問題が発生します。
次の問題が問題になります。
#include <stdio.h>
int main()
{
char * str = "Hello";
printf("\n%s \n", str);
*(str+1) = '3';
printf("\n%s \n", str);
return 0;
}
対応する分解
.file "dfd.c"
.section .rodata
.LC0:
.string "Hello"
.LC1:
.string "\n%s \n"
.text
.....
.....
そしてその結果は
Hello
Segmentation fault (core dumped)
X86_64でgccバージョン4.6.3(Ubuntu / Linaro 4.6.3-1ubuntu5)を使用しています。
str は文字列定数へのポインタで、文字列のメモリは読み取り専用セクションに割り当てられます。文字列の内容を変更しようとすると、結果は未定義です。ただし、常に同じメモリ位置にバインドされている配列名と比較して、ポインターを変更して別のものを指すことができます。
#include <string.h>
char *str;
if((str = malloc(strlen("hello"))) != NULL)
return (null);
str = strcpy(str, "hello");
printf("%s\n", str); // should print hello
str[2] = '3';
printf("%s\n", str) // should print he3lo
ここで重要なのは、文字列に char を設定する前にメモリを割り当てることです。ただし、割り当てが苦手な場合は、いつでも char str[] = "hello"; を設定できます。