我很难理解为什么这段代码会这样执行。我不明白为什么当doThings执行时,它会给我一个Abort trap:6错误,但是当main中的循环执行时,它不会给我一个错误,并打印字符数组的有效部分(可以放入大小为30的数组中的值,文本为31个字符)。
简而言之,错误在doThings中的snprintf语句中。注释它会破坏代码(显然),但不会发生中止陷阱6。但为什么它会导致一个错误,而执行时没有错误的主要?
#include <stdio.h>
#include <string.h>
#define BUF_LEN 30
void doThings(char *buffer)
{
char anotherBuffer[BUF_LEN];
int i;
for (i = 0; i <= BUF_LEN; i++)
{
char temp[2];
snprintf(temp, 2, "%s", buffer + i);
strcat(anotherBuffer, temp);
}
printf("%s\n", anotherBuffer);
}
int main()
{
char aString[BUF_LEN] = "1234567890123456789012345678901";
printf("%s\n", aString);
//This is doThings within main
int i;
for (i = 0; i <= BUF_LEN; i++)
{
char temp[2];
snprintf(temp, 2, "%s", aString + i);
printf("%s", temp);
}
printf("\n");
//Now execute doThings passing aString
doThings(aString);
return 0;
}
最佳答案
首先,通过说
char aString[BUF_LEN] = "1234567890123456789012345678901";
您提供了一个31
char
s的列表作为30个字符数组的初始值设定项。这并没有错,但是尝试使用char
数组作为字符串将导致UB,因为没有空终止符。或者将
BUF_LEN
定义为32,或者让编译器决定大小,使用类似于 char aString[ ] = "1234567890123456789012345678901";
其中编译器根据提供的初始值设定项的长度为数组选择正确的大小,包括终止的空值。
再说一遍,我相信,这也和你的循环状况有关。而不是
for (i = 0; i <= BUF_LEN; i++)
你应该这么做
for (i = 0; i < BUF_LEN; i++)
否则,当C数组使用基于0的索引时,你将是“AA>”。这样,您将访问调用off-by-one的绑定外内存。
另外,正如undefined behavior正确提到的,您正在使用
strcat(anotherBuffer, temp);
而
anotherBuffer
未初始化。根据定义,strcat()
的第一个参数应该是指向字符串的指针,即指向以空结尾的char
数组的指针。一开始,anotherBuffer
的内容是不确定的,更不用说有一个空终止符了。您应该始终初始化自动局部变量,就像在本例中一样,char anotherBuffer[BUF_LEN] = {0};
关于c - snprintf导致功能内的中止陷阱6但不是主要的,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40334281/