使用memset填充数组显示垃圾

时间:2017-06-22 11:11:44

标签: c++

我被困在一个简单的代码段中:

#include <iostream>
#include <stdio.h>
#include<cstring>
#include <algorithm>
int main()
{

        int l;
        std::cin >> l;
        char leading[l];
        //std::fill_n(leading, l, '0');
        memset(leading, '0', sizeof(char)*l);
        std::cout << "->" << leading << "<- strlen=" << strlen(leading) << std::endl;
}

以下是多次运行的结果(与std::fill_n相同的问题):

~/test$ g++ ptr.cpp 
~/test$ ./a.out 
3
->000*�<- strlen=6
~/test$ ./a.out 
7
->0000000<- strlen=7
~/test$ ./a.out 
6
->000000<- strlen=6
~/test$ ./a.out 
5
->00000<- strlen=6
~/test$ ./a.out 
2
->00@��<- strlen=6

我是否需要寻找其他工作?

更新 正如我稍后将在sprintf中使用此数组,我不想使用null终止符。还有更好的选择吗?

3 个答案:

答案 0 :(得分:2)

'0' '\0'相同,这可能是您想要的。 (C ++支持的 encoding 系统不允许将字符文字'0'设置为值0。)

在此内存块上使用strlen的行为将是未定义的。

如果要填充字符0,请记住在内存块中添加NUL终结符,以便可以使用C类型字符串函数(以及<<)。

答案 1 :(得分:2)

strlenoperator<<(basic_ostream&, char*)都有前提条件,指针参数指向以空字符结尾的字符串。您的数组不会以空值终止,因此您违反了这些前提条件。因此,程序的行为未定义。

  

更新:我不使用null终止符。还有更好的选择吗?

由于您已经知道长度strlen,因此无需替代l

对于非空终止字符数组的流式传输,您可以使用迭代器:

std::ostream_iterator<char> it(std::cout);
std::copy(leading, std::end(leading), it);

PS。

std::cin >> l;
char leading[l];

这在C ++中是不正确的。数组的大小必须是编译时常量。

答案 2 :(得分:1)

因为strlen和cout都依赖于null终止符来指示字符串的结尾