Sprintf崩溃我的程序

时间:2016-12-23 22:26:54

标签: c pointers printf

  

我只是尝试使用sprintf连接一些字符串,但我有这个问题,   我不明白为什么我的程序在C中使用sprintf崩溃了。为什么这个代码会运行?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char* dateTime = malloc(16*sizeof(char));

    printf("Date: %s\n", __DATE__);
    printf("Time: %s\n", __TIME__);

    sprintf (dateTime, "%s, %s\0", __DATE__, __TIME__);

    printf("%s", dateTime);
    free(dateTime);

    return 0;
}
  

这不是吗?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char* dateTime = malloc(16*sizeof(char));

    //printf("Date: %s\n", __DATE__);
    //printf("Time: %s\n", __TIME__);

    sprintf (dateTime, "%s, %s\0", __DATE__, __TIME__);

    printf("%s", dateTime);
    free(dateTime);

    return 0;
}

2 个答案:

答案 0 :(得分:7)

在我的编译器上,您创建的字符串长度为21个字符(Dec 23 2016, 23:29:57),因此您基本上为字符串分配了太少的字节。

您获得了未定义的行为。所以它在没有printf语句的情况下崩溃,并且与它们一起工作,因为计算机没有做同样的事情,但它仍然是错误的。

顺便说一下,你可以通过这样做来安全地实现你想要的东西:

const char *dateTime= __DATE__ " " __TIME__;

因为__DATE____TIME__已经是字符串宏。预处理器可以在编译时进行连接。

如果您想计算所需的字符数,可以将snprintfNULL缓冲区一起使用(仅限c99):

  

使用零bufsz和缓冲区空指针调用snprintf对于确定包含输出所需的缓冲区大小很有用:

const char *fmt = "sqrt(2) = %f";
int sz = snprintf(NULL, 0, fmt, sqrt(2));
char buf[sz + 1]; // note +1 for terminating null byte
snprintf(buf, sizeof buf, fmt, sqrt(2));

http://en.cppreference.com/w/c/io/fprintf

答案 1 :(得分:4)

对于sprintf,您的缓冲区似乎太小了:

char* dateTime = malloc(16*sizeof(char));

__DATE____TIME__总是占用超过15个字节(不包括NUL字符)。写入数组边界会导致未定义的行为。