我很难理解为什么这段代码会这样执行。我不明白为什么当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";

您提供了一个31chars的列表作为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/

10-16 23:21