我认为这是使用sprintf的常用方法:
char pText[x];
sprintf(pText, "helloworld %d", Count );
但是如果char指针分配的内存少于打印到?
,究竟会发生什么?即。如果x小于sprintf的第二个参数的长度怎么办?
我问,因为我在sprintf语句后面的代码中遇到了一些奇怪的行为。
答案 0 :(得分:10)
一般来说,“确切地”回答会发生什么是不可能的。这样做会调用所谓的Undefined behavior,这基本上意味着可能发生任何事情。
最好避免这种情况,并在可用的情况下使用安全功能:
char pText[12];
snprintf(pText, sizeof pText, "helloworld %d", count);
注意snprintf()
如何获取一个额外的参数,即缓冲区大小,并且写入的空间不会超过空间。
答案 1 :(得分:6)
这是一个常见错误,并在覆盖char数组后导致内存。因此,例如,在char数组之后的内存中可能会有一些整数或其他数组,并且这些数组会被文本覆盖。
详细了解整个问题(缓冲区溢出)here。还有一个注释,一些架构提供了一个snprintf例程,它具有第四个参数,用于定义最大长度(在您的情况下为x)。如果你的编译器不知道它,你也可以自己编写它以确保你不会得到这样的错误(或者只是检查你是否总是分配了足够的空间)。
请注意,此类错误后的行为未定义,可能导致非常奇怪的错误。变量通常在可被4整除的内存位置对齐,因此在大多数情况下,如果你写了一个或两个字节太多(即忘记为NUL定位),你有时不会注意到错误,但在其他情况下会出现奇怪的错误案例。这些错误很难调试,因为其他变量会发生变化,错误通常会发生在代码的完全不同的部分。
答案 2 :(得分:3)
这称为缓冲区溢出。
sprintf
将覆盖pText
地址跟随的内存。由于pText
在堆栈上,sprintf
可以覆盖局部变量,函数参数和返回地址,从而导致各种错误。这种代码导致许多安全漏洞 - 例如攻击者使用缓冲区溢出来写一个指向他自己代码的新返回地址。
答案 3 :(得分:2)
此情况下的行为未定义。通常情况下,你会崩溃,但你也可能看到没有不良影响,奇怪的值出现在无关的变量和那种事情。您的代码也可能调用错误的函数,格式化您的硬盘驱动器并杀死其他正在运行的程序。最好通过为缓冲区分配更多内存来解决此问题。
答案 4 :(得分:1)
我已多次这样做,您将收到内存损坏错误。 AFAIK,我记得我做过这样的事情: -
vector<char> vecMyObj(10);
vecMyObj.resize(10);
sprintf(&vecMyObj[0],"helloworld %d", count);
但是当调用vector的析构函数时,我的程序会收到内存损坏错误,如果size小于10,它将成功运行。
答案 5 :(得分:0)
你能拼写Buffer Overflow吗?一个可能的结果是堆栈损坏,并使您的应用程序容易受到基于堆栈的利用。