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

发布于 2025-01-05 12:39:20 字数 832 浏览 2 评论 0原文

嗨,我的问题有点难以解释,所以我将在这里发布我的代码部分并用示例解释问题。

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

//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 个随机字符,当然我不想输出它们。

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

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

Hi my problem is kind of difficult to explain so I'll just post my code section here and explain the problem with an example.

This code here has a big and a small array where the big array gets split up in small parts, is stored in the small array and the small array is outputting its content on the screen.
Afterwards I free the allocated memory of the small array and initialize it again with the next part of the big array:

//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

now my problem is that the outputted string has everytime some random symbols at the end. for example "some_characters_here...last_char_hereRANDOM_CHARS_HERE".

after looking deeper into it I found out that splitArray actually doesnt have a size of 50 but of 64 with the null terminator at 64.
so when I copy from bigArray into splitArray then there are still the 14 random characters left after the real string and of course I dont want to output them.

A simple solution would be to manually set the null terminator in the splitArray at [50] but then the program fails to delete the array again.

Can anybody help me find a solution for this? Preferably with some example code, thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

瞄了个咪的 2025-01-12 12:39:20

刚刚设置了splitArray[49] = 0,程序怎么会“再次删除数组失败”呢?不要忘记,长度为 50 的数组的索引范围为 0 到 49。splitArray[50] = 0 正在写入分配给 splitArray 的内存之外,其中所有所带来的后果。

How does the program "fail to delete the array again" if you just set splitArray[49] = 0? Don't forget, an array of length 50 is indexed from 0 through 49. splitArray[50] = 0 is writing to memory outside that allocated for splitArray, with all the consequences that entails.

落叶缤纷 2025-01-12 12:39:20

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

When you allocate memory for the splitArray the memory is not filled with NULL characters, you need to explictly do it. Because of this your string is not properly NULL terminated. To do this you can do char* splitArray = new char[51](); to initialize with NULL character at the time of allocation itself (note that I am allocating 51 chars to have the extra NULL character at the end). . Also note that you need to do delete[] splitArray; and not delete splitArray;.

东北女汉子 2025-01-12 12:39:20

函数 strncpy 的缺点是,如果源字符串包含超过 50 个字符,它不会终止目标字符串。看来你的情况确实如此!

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

The function strncpy has the disadvantage that it doesn't terminate the destination string, if the source string contains more than 50 chars. Seems like it does in your case!

If this really is C++, you can do it with std::string splitArray(bigArray+startPoint, 50).

花伊自在美 2025-01-12 12:39:20

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

  1. 如果您使用 new [] 进行分配,则需要使用 delete [] 释放(而不是 delete >)
  2. 你为什么要使用免费商店?据我所知,您不妨使用本地数组。
  3. 如果要在数组中存储 50 个字符,则需要 51 个字符作为终止空字符。

你想要一些代码:

while(/* condition */)
{
    // your logic

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

    // do stuff with splitArray
    // no delete
}

I see a couple of problems with your code:

  1. If you allocate by using new [], you need to free with delete [] (not delete)
  2. Why are you using freestore anyway? From what I can see you might as well use local array.
  3. If you want to store 50 characters in an array, you need 51 for the terminating null character.

You wanted some code:

while(/* condition */)
{
    // your logic

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

    // do stuff with splitArray
    // no delete
}
尽揽少女心 2025-01-12 12:39:20

只要这样做就足够了:

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

我真的很想知道你为什么要这样做。这更干净:

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

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

char const *s = split.c_str();

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


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

Just doing this will be sufficient:

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

I'd really question why you're doing this anyway though. This is much cleaner:

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

it still does the copy, but handles (de)allocation and termination for you. You can get the underlying character pointer like so:

char const *s = split.c_str();

it'll be correctly nul-terminated, and have the same lifetime as the string object (ie, you don't need to free or delete it).


NB. I haven't changed your original code, but losing the magic integer literals would also be a good idea.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文