C 即使导致缓冲区溢出,将int转换为string仍然有效

C 即使导致缓冲区溢出,将int转换为string仍然有效,c,string,int,C,String,Int,我正在尝试使用以下代码将int转换为C字符串: static char* copyString(const char* str) { char* new_String = malloc(strlen(str) + 1); return strcpy(new_String, str); } static char* mallocIntToString(const int num) { char s[10]; // ************* sprintf(s,

我正在尝试使用以下代码将
int
转换为C字符串:

static char* copyString(const char* str)  
{
    char* new_String = malloc(strlen(str) + 1);
    return strcpy(new_String, str);
}
static char* mallocIntToString(const int num)
{
    char s[10]; // *************
    sprintf(s, "%d", num);
    char* copy = copyString(s);

    return copy;
}
我在想我应该在这行中插入的最大数字是多少
chars[10]

我使用了10,因为它是整数的最大位数。然而,当我使用
chars[9]时,这段代码也适用于我,正在尝试将数字2147483647转换为字符串,怎么可能

我在想我应该在
chars[10]行中插入的最大数字是多少

您应该在
中定义的
INT\u MAX
INT\u MIN
之间插入最大长度
INT_MIN
应该是
-2147483648
,因此需要11+1=12个字符(另外一个字符用于字符串终止符
\0

正确的实施方法是:

static char* mallocIntToString(const int num)
{
    char *s;

    s = malloc(12);
    if (s == NULL)
        return NULL;

    sprintf(s, "%d", num);    
    // Should probably also check for error here.

    return s;
}
然而,当我使用
chars[9]时,这段代码也适用于我
,试图将数字
2147483647
转换为字符串,怎么可能

您正在调用未定义的行为,因为在数组末尾写入是未定义的行为。如果这样做,任何事情都可能发生。该程序不能保证正常工作,但纯粹出于巧合,它似乎仍然可以工作。代码中发生的情况是,由于变量是在堆栈上定义的,并且堆栈是可写的,因此多写入一个或两个字节不会有太大变化,因为程序仍在写入有效内存。尽管如此,这仍然是未定义的行为,应该不惜一切代价避免


100%清楚地说,即使使用
chars[10],您也会调用未定义的行为
字符[11]
,因为在
INT\u MIN
的情况下,终止符将被写入数组边界之外。

请看
。例如,
INT\u MIN
INT\u MAX
可以分别定义为
-2147483648
+2147483647
。两者都是错误的,代码恰好工作。10位数字需要11个字符,因为必须有空间用于终止
“\0”
。即使如此,你也会遇到麻烦−2147483648,其中需要一个额外字符作为符号。未定义的行为是未定义的。任何事情都可能发生,包括今天“工作”和下周中断。仅供参考:
strdup
已经完成了
copyString
函数正在执行的操作(以及正确的错误检查)。为什么还要复制生成的字符串呢?只需在堆上分配一个大小合适的缓冲区,并使用
sprintf()
将结果写入其中即可。嘿,马可,谢谢你非常详细的回答,你对我说得非常清楚:)@NivBehar不客气。如果我回答了你的问题,你可以用左边的复选标记按钮接受我的回答,这样你的帖子就可以标记为已解决。