当我们不包括'\0';在C中字符串的末尾?
在C中,当我以这种方式初始化数组时:当我们不包括'\0';在C中字符串的末尾?,c,string,valgrind,null-terminated,C,String,Valgrind,Null Terminated,在C中,当我以这种方式初始化数组时: char full_name[] = { 't', 'o', 'a', 'n' }; 并用printf(“%s”,全名)打印 和valgrind一起运行我出错了 未初始化的值是通过堆栈分配创建的 为什么会发生这种情况?如果不在逗号分隔的括号内的初始值设定项列表的末尾提供'\0',从技术上讲,全名不是字符串,因为字符数组不是以null结尾的 只是想澄清一下,与初始值设定项是字符串文字不同,逗号分隔的列表不会自动计数并将终止的空字符放入数组中 因此,如
char full_name[] = {
't', 'o', 'a', 'n'
};
并用printf(“%s”,全名)打印代码>
和valgrind一起运行我出错了
未初始化的值是通过堆栈分配创建的
为什么会发生这种情况?如果不在逗号分隔的括号内的初始值设定项列表的末尾提供'\0'
,从技术上讲,全名
不是字符串,因为字符
数组不是以null结尾的
只是想澄清一下,与初始值设定项是字符串文字不同,逗号分隔的列表不会自动计数并将终止的空字符放入数组中
因此,如果定义为
char full_name[] = {
't', 'o', 'a', 'n'
};
数组的大小为4,其中包含't'
,'o'
,'a'
,'n'
奥托,以防
char full_name[] = "toan";
全名的大小为5,其中包含't'
,'o'
,'a'
,'n'
和'\0'
当您尝试将前一个数组与任何对字符串进行操作的函数(即,期望以null结尾的char
数组)一起使用时,您将得到以下结果,因为大多数字符串函数在搜索null结尾符时都会越界
在您的特定示例中,对于带有printf()
的%s
格式说明符,引用C11
标准,第§7.21.6.1章,fprintf()
函数描述(重点)
s
如果不存在l
长度修饰符,则参数应为指向初始值的指针
字符类型为.280)的数组的元素
写入(但不包括)终止空字符。如果
指定了精度,写入的字节数不超过该字节数如果
精度未规定或大于阵列尺寸时,阵列应
包含空字符。
这意味着,printf()
将查找空终止符来标记/理解数组的结尾。在您的示例中,缺少空终止符将导致printf()
超出分配的内存(full\u name[3]
)并访问绑定外内存(full\u name[4]
),这将导致UB。如果您没有在逗号分隔的括号内初始值设定项列表的末尾提供'\0'
,从技术上讲,full\u name
不是字符串,因为char
数组不是以null结尾的
只是想澄清一下,与初始值设定项是字符串文字不同,逗号分隔的列表不会自动计数并将终止的空字符放入数组中
因此,如果定义为
char full_name[] = {
't', 'o', 'a', 'n'
};
数组的大小为4,其中包含't'
,'o'
,'a'
,'n'
奥托,以防
char full_name[] = "toan";
全名的大小为5,其中包含't'
,'o'
,'a'
,'n'
和'\0'
当您尝试将前一个数组与任何对字符串进行操作的函数(即,期望以null结尾的char
数组)一起使用时,您将得到以下结果,因为大多数字符串函数在搜索null结尾符时都会越界
在您的特定示例中,对于带有printf()
的%s
格式说明符,引用C11
标准,第§7.21.6.1章,fprintf()
函数描述(重点)
s
如果不存在l
长度修饰符,则参数应为指向初始值的指针
字符类型为.280)的数组的元素
写入(但不包括)终止空字符。如果
指定了精度,写入的字节数不超过该字节数如果
精度未规定或大于阵列尺寸时,阵列应
包含空字符。
这意味着,printf()
将查找空终止符来标记/理解数组的结尾。在您的示例中,缺少空终止符将导致printf()
超出分配的内存(full\u name[3]
)并访问绑定外内存(full\u name[4]
),这将导致UB。,因为%s
格式说明符需要以空结尾的字符串,代码的结果行为未定义。您的程序被认为是格式不正确的,可以产生任何输出、不产生输出、崩溃等等。简而言之,不要那样做
这并不是说所有字符数组都必须以null结尾:该规则仅适用于用作C字符串的字符数组,例如传递给%s
格式说明符上的printf
,或传递给标准C库的strlen
或其他字符串函数
如果打算将char
数组用于其他用途,则不需要以null结尾。例如,此用途已完全定义:
char full_name[] = {
't', 'o', 'a', 'n'
};
for (size_t i = 0 ; i != sizeof(full_name) ; i++) {
printf("%c", full_name[i]);
}
由于%s
格式说明符需要以null结尾的字符串,因此代码的结果行为未定义。您的程序被认为是格式不正确的,可以产生任何输出、不产生输出、崩溃等等。简而言之,不要那样做
这并不是说所有字符数组都必须以null结尾:该规则仅适用于用作C字符串的字符数组,例如传递给%s
格式说明符上的printf
,或传递给标准C库的strlen
或其他字符串函数
如果打算将char
数组用于其他用途,则不需要以null结尾。例如,thi