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



嗨,我的问题有点难以解释,所以我只在这里发布我的代码部分,并用一个例子来解释这个问题。

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

//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,null终止符在64。所以当我从bigArray复制到splitArray中时,在实际字符串之后仍然有14个随机字符,当然我不想输出它们。

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

有人能帮我找到解决办法吗?最好提供一些示例代码,谢谢。

如果只设置splitArray[49] = 0,程序如何"再次删除数组失败"?别忘了,长度为50的数组的索引是从0到49。splitArray[50] = 0正在向分配给splitArray的内存之外的内存写入,这将带来所有后果。

当您为splitArray分配内存时,内存中没有填充NULL字符,您需要显式地进行分配。因此,您的字符串没有正确地以NULL结尾。要做到这一点,您可以执行char* splitArray = new char[51]();,在分配时使用NULL字符进行初始化(请注意,我正在分配51个字符,以便在末尾有额外的NULL字符)。还要注意,您需要执行delete[] splitArray;,而不是delete splitArray;

函数strncpy的缺点是,如果源字符串包含50个以上的字符,它不会终止目标字符串。在你的情况下似乎是这样!

如果这真的是C++,你可以用std::string splitArray(bigArray+startPoint, 50)来做。

我发现您的代码有几个问题:

  1. 如果使用new []进行分配,则需要使用delete [](而不是delete)进行释放
  2. 你为什么要使用自由商店?据我所见,您还不如使用本地数组
  3. 如果您想在一个数组中存储50个字符,那么终止null字符需要51个字符

你想要一些代码:

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

只要这样做就足够了:

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

我真的很怀疑你为什么要这么做。这要干净得多:

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

它仍然执行复制,但为您处理(取消)分配和终止。你可以得到下面这样的字符指针:

char const *s = split.c_str();

它将正确地以nul结尾,并且具有与字符串对象相同的生存期(即,不需要freedelete)。


注:。我没有更改您的原始代码,但丢失神奇的整数文字也是一个好主意。

最新更新