为什么未初始化的char数组充满了随机符号?

时间:2015-11-25 18:49:34

标签: c++ cuda char

我在 C ++

中有一段代码片段
char x[50];
cout << x << endl;

输出一些随机符号,如下所示: enter image description here

所以我的第一个问题是:这个输出背后的原因是什么?难道不是空格或至少是相同的符号吗?

我担心这个的原因是我在CUDA中编写程序而我在__global__函数中进行了一些字符操作,因此使用string会得到一个&#34 ;不允许调用主机功能&#34;错误。 但如果我正在使用&#34;足够大&#34; char数组(我操作的每个文本块大小不同,这意味着它不会总是完全使用char数组)它有时候没有完全填充,而且我留下了垃圾,就像下面挂着的图片一样文本:

enter image description here

所以我的第二个问题:有什么方法可以避免这种情况吗?

4 个答案:

答案 0 :(得分:2)

  

此输出背后的原因是什么?

自动变量中的值为不确定。标准没有指定它,因此它可能是您所说的空格,它可能是随机内容。

  

[...]有时没有完全填满,我离开了垃圾[...]

C中的字符串以空值终止,因此只要没有遇到空字节,任何专门用于打印字符串的例程都将循环。在未初始化的内存中,此空字节随机出现(或根本不出现)。这些怪异的尾随字符就是这样的结果。

  

有什么方法可以避免这种情况吗?

是。初始化它。

答案 1 :(得分:1)

(将在本文中假设x86)

  

这个输出背后的原因是什么?

这里大概是在装配时,当你char x[50];时发生的事情:

ADD ESP, 0x34 ; 52 bytes

基本上,堆栈向上移动0x34字节(必须可被4整除)。然后,堆栈上的空间变为 x。没有清洁,没有变化或推或弹,只有这个空间变成x。之前存在的任何内容(废弃的参数,返回地址,以前函数调用的变量)都将在x中。

这里大概是new char[50]时发生的事情:

1. Control gets passed to the allocator
2. The allocator looks for any heap of sufficient size (readas: an already allocated but uncommited heap)
3. If 2 fails, the allocator makes a new heap
4. The allocator takes the heap (either the found or allocated one) and commits it
5. The address of that heap is returned to your code where it is used as a char*

与堆栈相同,您可以获得任何数据。某些程序或系统可能具有在分配或提交时将堆分为零的分配器,其他分配器在分配但未提交时可能仅为零,而有些可能根本不为零。根据分配器的不同,您可能会获得干净的内存,或者可能会重新使用内存和脏内存。这就是为什么这里的值可以是非零并且不可预测的原因。

  

有什么方法可以避免这种情况吗?

对于堆内存,您可以在C ++中重载newdelete运算符,并始终将新分配的内存归零。您可以看到重载这些运算符here的示例。至于堆栈中的内存,你只需每次都将它归零。

ZeroMemory(myArray, sizeof(myarray));

或者,对于这两种方法,您可以远离裸数组并使用std :: vector或其他为您进行初始化的包装器。但是,您仍然希望确保初始化整数和其他数字或指针数据类型。

答案 2 :(得分:0)

不,没有办法避免它。 C ++不会自动初始化内置类型的自动变量(例如你的内置类型的数组),你需要自己初始化它们。

答案 3 :(得分:0)

为什么您遇到此代码的问题?

char x[50];
cout << new char[50] << endl;
cout << x << endl;

您使用新的字符[50]泄漏内存而没有相应的删除。

此外,未初始化的内存未定义,正如其他人所说,并且在大多数情况下,您会在该内存块中获得垃圾。更好的方法是初始化它:

char x[50] = {};
char* y = new char[50]();

然后记得稍后调用删除以释放内存。是的,操作系统会为你做,但这绝不是编写好程序的方法。