C ++ char数组正确移动null终止符?

时间:2012-02-15 12:25:02

标签: c++ arrays null char terminator

您好我的问题很难解释所以我只是在这里发布我的代码部分并用一个例子解释问题。

这里的代码有一个大的和一个小的数组,其中大数组被分成小部分,存储在小数组中,小数组在屏幕上输出其内容。
然后我释放小数组的已分配内存,并使用大数组的下一部分再次初始化它:

//this code is in a loop that runs until all of the big array has been copied
char* splitArray = new char[50];        
strncpy(splitArray, bigArray+startPoint, 50); //startPoint is calculated with every loop run, it marks the next point in the array for copying

//output of splitArray on the screen here

delete splitArray;
//repeat loop here

现在我的问题是输出的字符串每次都有一些随机符号。例如"some_characters_here...last_char_hereRANDOM_CHARS_HERE".

在深入研究之后,我发现splitArray实际上的大小不是50而是64,空终结符为64。 所以当我从bigArray复制到splitArray时,真正的字符串后面仍然有14个随机字符,当然我不想输出它们。

一个简单的解决方案是在[50]的splitArray中手动设置空终止符,但程序无法再次删除该数组。

有人可以帮我找到解决方案吗?最好用一些示例代码,谢谢。

5 个答案:

答案 0 :(得分:0)

如果您只设置splitArray[49] = 0,程序如何“无法再次删除数组”?不要忘记,长度为50的数组从0到49被索引。splitArray[50] = 0正在写入分配给splitArray之外的内存,并带来所有后果。

答案 1 :(得分:0)

splitArray分配内存时,内存中没有填充NULL字符,您需要明确地执行此操作。因此,您的字符串未正确地以NULL结尾。为此,您可以char* splitArray = new char[51]();在分配时使用NULL字符进行初始化(请注意,我将分配51个字符以在末尾添加额外的NULL字符)。 。另请注意,您需要执行delete[] splitArray;而不是delete splitArray;

答案 2 :(得分:0)

这样就足够了:

char* splitArray = new char[50 + 1];        
strncpy(splitArray, bigArray+startPoint, 50);
splitArray[50] = '\0';

我真的很怀疑你为什么要这样做呢。这更清洁:

std::string split(bigArray+startPoint, 50);

它仍然执行复制,但为您处理(de)分配和终止。您可以像下面这样获取基础字符指针:

char const *s = split.c_str();

它将被正确地nul终止,并且与字符串对象具有相同的生命周期(即,您不需要freedelete它。


NB。我没有改变你原来的代码,但是丢失魔法整数文字也是个不错的主意。

答案 3 :(得分:0)

如果源字符串包含超过50个字符,则函数strncpy的缺点是它不会终止目标字符串。看起来就像你的情况一样!

如果这确实是C ++,您可以使用std::string splitArray(bigArray+startPoint, 50)

答案 4 :(得分:0)

我发现您的代码存在一些问题:

  1. 如果您使用new []进行分配,则需要使用delete [](而非delete
  2. 免费
  3. 为什么你还在使用freestore?从我所看到的你也可以使用本地数组。
  4. 如果要在数组中存储50个字符,则终止空字符需要51个字符。
  5. 你想要一些代码:

    while(/* condition */)
    {
        // your logic
    
        char splitArray[51];
        strncpy(splitArray, bigArray+startPoint, 50);
        splitArray[50] = '\0';
    
        // do stuff with splitArray
        // no delete
    }