Q1。为什么我在字符串缓冲区中获得不同的大小?
三个输出:
size_t
在您的系统中是四个字节。这是原因sizeof(size)
是 4,但不是因为 assignment size = 4
。当然,您的 printf 大小值也是 4。
- 其次,
strlen(str)
为您提供 string 的长度"hello"
,即由 5 个字符组成。(字符串长度不包括\0
nul 字符)。
C 中的字符串是char[N]
(数组)类型。第 3 个 pritnfsizeof("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"
字符串,因为str
没有分配足够的空间来保存完整的字符串,这样做会导致缓冲区溢出问题,即运行时 C/C++ 中的未定义行为。