这就是我所做的:
#include <stdio.h>
#include <string.h>
int main() {
char name[] = "longname";
printf("Name = %s \n",name);
strcpy(name,"evenlongername");
printf("Name = %s \n",name);
printf("size of the array is : %d",sizeof(name));
return 0;
}
它有效,但是如何?我认为一旦将内存分配给程序中的数组,就无法更改它。但是,该程序的输出为:
Name = longname
Name = evenlongername
size of the array is 9
因此,编译器确认数组的大小仍为9。如何存储大小为15个字节(包括字符串终止符)的单词'evenlongername'?
答案 0 :(得分:6)
在这种情况下,name
被分配为适合"longname"
的9字节。当您将"evenlongername"
复制到其中时,您将在该数组的边界之外进行写入。在界限外书写是未定义的行为,这意味着它可能会或可能不会起作用。有时候,它会起作用,有时候,您会遇到段错误,而有时会出现奇怪的行为。
答案 1 :(得分:3)
因此,编译器确认数组的大小仍然为9。如何存储大小为15个字节(包括字符串终止符)的单词'evenlongername'?
您正在使用危险功能(请参见Bugs)strcpy
,该功能会在不知道其大小的情况下将源字符串盲目地复制到目标缓冲区。如果将15个字节复制到大小为9个字节的缓冲区中,则实际上已经溢出。如果内存访问有效且未覆盖某些重要内容,则程序 可能会正常运行。
因为C是一种较低级的编程语言,所以C char[]
是内存的“准系统”映射,而不是像C ++ std::vector
这样的“智能”容器,它可以自动为您管理大小您可以动态添加和删除元素。如果您仍然不太了解C的原理,建议您阅读*YOU* are full of bullshit
。非常经典,很有收获。
答案 2 :(得分:2)
在char数组上使用sizeof
将返回缓冲区的大小,而不是缓冲区中以null终止的字符串的长度。如果您使用strcpy
尝试使数组溢出并且恰好起作用(这仍然是未定义的行为),则sizeof
仍将报告声明时使用的大小。那永远不会改变。
如果您感兴趣的是观察字符串长度如何随着不同的分配而变化:
strlen
中使用函数<string.h>
,该函数将为您提供字符串的实际长度,而不是缓冲区的长度,缓冲区的长度在声明后是恒定的。