【问题标题】:New allocates too much memory [duplicate]新分配太多内存[重复]
【发布时间】:2013-08-06 20:17:08
【问题描述】:

我正在编写用于合并两个 C 字符串的简单函数。在尝试动态分配新的内存块时,我发现:

char * out = new char[size];
std::cout << strlen(out) <<std::endl;

size 为 4 时返回 16,size 为 22 时返回 40,依此类推。 有谁知道它为什么会这样以及如何为具有一定数量字符的 c-string 分配内存?

【问题讨论】:

  • 你没有初始化字符串。 strlen() 需要一个以 0 结尾的缓冲区。被问了很多次...
  • 是的 - 只要我在一个问题中看到 strlen() ......
  • 目前尚不清楚这是否与提议的原件重复。该问题涉及将strlen 应用于已初始化但不包含终止空字符的数组。此问题将strlen 应用于未初始化的数组。从问题中不清楚混淆是关于strlen 的操作方式还是关于new 是否以及如何初始化以这种方式分配的数组。
  • @H2CO3 - 就像我在整个空闲时间都在阅读 SO 并且知道这一点。问题是分配问题,但缺少字符串终止符。这只是一件简单的事情,因为您很长时间没有使用它,所以您会从脑海中浮现。它总是让我感到惊讶——SoftDev 的家伙如何在被问到一个简单的问题时获得如此大的打击。好建议 - 如果它对你的灵魂造成太大伤害,而你要表达它的作用,而不是给出真正的答案 - 那就不要这样做。
  • @EricPostpischil 对,你有更好的骗子吗?我很有信心这是重复的。

标签: c++ c char new-operator


【解决方案1】:

分配的内存未初始化。 strlen() 只是不断地通过内存充电,直到遇到空字符 ('\0')。由于你还没有初始化out指向的内存,这块内存的内容是未定义的,所以strlen()的行为也是如此。

strlen() 测量分配的大小,因此您对 new 分配过多内存的解释是不正确的,因为您使用的工具是用来测量分配的大小根本不这样做。

在您的情况下,strlen() 正在读取超出此分配的边界。在这种情况下,结果可能是“错误”值(如您在此处看到的),或者您的程序可能会崩溃。

【讨论】:

  • new 初始化它创建的一些对象而不是其他对象,因此解释为什么此分配没有初始化分配的内存可能很有用。
【解决方案2】:

使用new分配内存不会初始化内存:

char * out = new char[size];

// Add this code to initialize out
memset(out,'A',size-1);
out[size-1]='\0';

std::cout << strlen(out) <<std::endl;

【讨论】:

  • 从技术上讲,new char[size]() 仍在使用 new 并且确实如此。
  • 只是代码片段。之后,我有一个 for 循环将字符的确切数量(等于变量“大小”)放入“输出”字符 * 中。例如 - 而不是 'aabb' 字符串,我有 'aabbrrrrzzzzzzzz'
  • @pawels1991,它们中的任何一个都是空终止符吗?
  • @pawels1991,至少,最后一个?
  • 使用 NULL 表示 0 可能会与您的编译器一起编译,但在语义上使用绝对是错误的。 NULL 表示 NULL 指针,而不是 NUL 终止符。
猜你喜欢
  • 1970-01-01
  • 2012-06-20
  • 2015-12-04
  • 2011-08-04
  • 2013-12-19
  • 2020-01-31
  • 1970-01-01
  • 2015-12-03
  • 1970-01-01
相关资源
最近更新 更多