数组包含的元素多于声明的大小。为什么这样做?

时间:2018-04-03 17:16:01

标签: c++

我宣布char linkk[23];

我用

打印
for(int i=0;i<23;i++)
    cout<<linkk[i];

我没有注意到任何错误,但是当我打开链接时,在23个元素之后弹出了一个!v。

char arr[]="start C:\\Users\\user\\Downloads\\chrome-win32\\chrome-win32\\chrome.exe ";
strcat(arr, linkk);
string openL=arr;
system(openL.c_str());

因此,在加入数组之前,我删除了linkk中的两个元素。

linkk[24]='\0';
linkk[23]='\0';

它有效,但我不明白!v来自哪里。

PS:我是个菜鸟。

4 个答案:

答案 0 :(得分:3)

这里有几个问题。但是,要回答您的具体问题,您需要说明如何初始化linkk,我在您的问题中没有看到。

一个很大的问题是使用strcat将linkk连接到arr。声明arr的方式,它只会大到足以容纳你初始化它的文字字符串。因此,strcat将溢出该缓冲区。

不使用长度说明符的旧版C函数几乎总是危险的,不应该在现代编程中使用。其中包括strcat, strcpy, and others。因为您正在使用C ++,并且最后将所有内容转换为std :: string,所以我建议一直使用std :: string并避免使用原始字符数组:

std::string linkk;
// Initialize linkk however you want. Again, this wasn't specified in your question.

std::string program("start C:\\Users\\user\\Downloads\\chrome-
win32\\chrome-win32\\chrome.exe ");
std::string openL = program + linkk;
system(openL.c_str());

答案 1 :(得分:1)

最有可能的是,linkk没有被正确地终止。当你打印出来时,你没有注意到这一点,因为你一次打印char

此代码的另一个问题是,在使用strcat时,您会溢出目标缓冲区。我建议对所有这些变量使用std::string

答案 2 :(得分:1)

引用the documentation

  

char *strcat( char *dest, const char *src );
  如果目标数组不足以容纳src和dest的内容以及终止空字符,则行为是未定义的。

目标数组不足以容纳两个字符串。这意味着strcat具有未定义的行为(最有可能写入其他内容正在使用的内存中,但几乎任何都可以发生)。

虚假!v是可能造成的后果之一 - 但同样,任何事情都可能发生。指定足够大的arr或使用std::string的C ++路由。

答案 3 :(得分:0)

在C中,您必须确保目标数组足够大以容纳其当前字符串以及您正在连接的其他字符串。由于您显然使用C ++,因此以C ++方式声明字符串:

const std::string yourFirstString ="something something chrome.exe ";
const std::string link = "<link here>";

然后,只需添加两个字符串:

const std::string strOpenLink = yourFirstString + link;

你不应该混合C和C ++字符串,因为它既令人困惑又更多工作,因此更容易出错。

对于您看到的随机字符串,从您的代码判断,linkkk数组未初始化,因此您在堆栈上分配数组之前获得了该内存位置中存在的随机值。您可以使用memset将其清零,也可以立即对其进行初始化。