Q1. 文字列バッファで異なるサイズを取得するのはなぜですか?
3 つの出力:
size_t
あなたのシステムでは4バイトです。これはsizeof(size)
4 の理由ですが、割り当てのためではありませんsize = 4
。もちろん、printf サイズの値も 4 です。
- 次に、5 文字で構成される
strlen(str)
string の長さを示します。"hello"
(文字列の長さにヌル文字は含まれません\0
)。
C の文字列はchar[N]
(配列) 型です。3 番目の pritnf のsizeof("hello")
値は 6
、"hello"
文字列が 6 文字の長さの配列であるためです (文字列の終端は\0
nul を含み、hello のタイプは ですchar[6]
)。
メモリ"hello"
文字列には、以下の図のように格納されます。
str 23 24 25 26 27 28
+----+ +----+----+----+----+----+----+
| 23 | | h | e | l | l | o | \0 |
+----+ +----+----+----+----+----+----+
Address of hello string is first address = 23
str: is pointer, used to store address of hello string
割り当てstr = "hello";
は、基本的に、上の図に示したように、文字列 hello のアドレスをポインター変数に格納しますstr
。
Q2. 4 バイトだけを割り当てた場合、6 バイトのサイズの 5 文字の文字列を格納できるのはなぜですか
実際には、「hello」文字列を動的に割り当てられたスペースにコピーしていません。最初 str
に含まれていたのは、 によって返されたアドレスmalloc()
です。しかし、代入文のためstr = "hello";
、割り当てられたメモリのメモリアドレスを代入文の定数文字列リテラル「hello」で上書きしました。
これを理解するために、次の例を実行できます。
#include<stdio.h>
int main(){
size_t size = 6;
char *str = malloc(size);
printf("\n malloc str: %p", str);
str = "hello";
printf("\n hello str: %p", str);
return 1;
}
出力:
malloc str: 0x804a078
hello str: 0x8048609 // allocated address lost
Codepade リンク
(補足: free() を使用して明示的に割り当てを解除するときに必要になるため、動的に (明示的に) 割り当てられたメモリのアドレスを失うことはありません。 )
割り当てられたスペースにコピーする場合は、(1) 各メモリ位置にアクセス/インデックス付けして割り当てるか、(2) ライブラリ関数を使用して割り当てることができますstrcpy()
。
たとえば、試してみてください:
str[0] = 'a';
str[1] = 'b';
str[2] = 'c';
str[3] = '\0'; // nul termination is important
or
strcpy(str, "abc"); // strcpy add nul itself
ただし、完全な文字列を保持するのに十分なスペースが割り当てられていない"hello"
ため、文字列をコピーできません。これを行うと、実行時に C/C++ で未定義の動作であるバッファ オーバーランの問題が発生します。str