2016-07-06 27 views
3
#include<iostream> 
#include<string.h> 
using namespace std; 
int main() 
{ 

    char p [] = "TEST"; 
    strcat (p, "VAL"); 
    cout << p; 
    return 0; 
} 

如果我所理解的是正确的,像char p [] =“TEST”;将从堆栈分配空间。当我为这样的字符串调用strcat()时,如何调整p []的存储以容纳额外的字符?是否有效的字符串添加像char p [] =“测试”字符数组使用strcat

最后一个cout打印“TESTVAL”。像这样调用strcat是否有效?如果是的话,这是如何工作的?我的理解可能会有问题,但感觉就像我失去了联系。所以这可能很容易成为一个愚蠢的问题。请说明一下。

回答

8

存储未调整,调用无效,代码的行为未定义。

+0

在这种情况下,我想知道为什么输出没有任何运行时问题是正确的? – NeonGlow

+3

@NeonGlow纯粹的运气。 – Galik

+2

@NeonGlow只是运气不好。尝试'strcat'的一些比'“VAL”更大的尺寸“。例如,使用这个答案在我的机器上崩溃。 – molbdnilo

2

p预留5个字符的空间(空终止符为4 + 1)。然后再添加3个需要8个空间的字符(空值为7 + 1)。你没有足够的空间,将覆盖堆栈。根据您的编译器和编译设置,您可能没有看到任何差异,编译器在堆栈变量之间留下空格。在优化版本构建中,您可能会遇到崩溃。

如果您将代码更改为如下所示,则应该看到sentinel1 & 2不再为0(取决于编译器哪一个会被丢弃)。

#include<iostream> 
#include<string.h> 
using namespace std; 
int main() 
{ 
    int sentinel1 = 0; 
    char p [] = "TEST"; 
    int sentinel2 = 0; 
    strcat (p, "VAL"); 
    cout << p << sentinel1 << sentinel2; 


    return 0; 
} 
3

当你写

char buffer[] = "some literal"; 

膨胀以

char buffer[sizeof("some literal")] = "some literal"; 

其具有存储"some literal"确切大小,仅此而已。

当您在当前缓冲区的末尾连接另一个字符串时 - 您编写超出数组的边界 - 具有未定义的行为。

另一个问题是,在C++中,我们通常使用std::string来处理字符串,它会自动为我们完成所有的内存调整。

+0

谢谢char buffer [sizeof(“some literal”)] =“some literal”;我从来不知道这是如何在内部工作的 – NeonGlow

+0

这不一定是内部工作原理的描述。它是以C或C++开发人员将理解的方式描述效果。没有要求C编译器内部使用'sizeof'来计算提供的字符串文字的长度。 – Peter

+0

@彼得:明白了。谢谢。 – NeonGlow

相关问题