【问题标题】:Erasing a Char[]擦除一个字符[]
【发布时间】:2010-09-23 06:02:09
【问题描述】:

好的,我正在处理别人的代码。他们经常这样做:

char description[256];
description[0]=0;

我知道这会将 \0 放在字符数组的第一个位置。但这甚至是擦除字符串的安全方法吗?

Visual Studio 也不断报告内存泄漏,我几乎将这与使用的字符串联系起来。

附言。是的,我知道 std::string,是的,我使用它。这不是我的代码。

【问题讨论】:

  • 能否澄清一下“我已经将这与使用的字符串联系起来了”?我无法完全解析它...

标签: c++ c arrays string char


【解决方案1】:

要将字符串初始化为0,你可以这样做:

char description[256] = {0};

这将为数组的每个元素分配 0。

仅将第一个元素设置为 0 ('\0') 不会删除其内容。它甚至不保证整个字符串都设置为空字符。

正如其他人所说,您不能“擦除”静态创建的对象,直到函数关闭,当它被放弃时。从技术上讲,当函数被放弃时它也不会被删除——堆栈指针只是被改变了。如果您对正在删除的数据感到疑虑,您应该遍历数组,将每个条目设置为 0 ('\0')。

【讨论】:

    【解决方案2】:

    将 char 数组的第一个元素设置为 \0 足以确保 'description' 是格式正确的实际字符串。元素 1 到 255 都可以是垃圾,只要元素 0 为 0,描述就是零长度字符串。

    您不必担心上面发布的代码中的内存泄漏,因为数组是在堆栈上分配的。一旦它从堆栈中掉下来(超出范围),char 数组就会被释放。

    【讨论】:

      【解决方案3】:

      这个字符串是在堆栈上分配的,所以在它被调用的函数返回之前没有办法释放它使用的内存(当它会自动发生时)。除非您以递归方式调用此函数*,否则这最终不会成为内存泄漏,因为一旦函数返回,空间将用于未来的堆栈帧。如果您担心安全性,您应该循环遍历字符串的元素并将其清零。

      如果你想要一个 free()-able 内存块,你可以执行以下操作并在堆上分配数组:

      char *str = malloc(256*sizeof(char)); // str now is a pointer to a 256-char array
      ...
      // some code here
      ...
      free(str); // free the memory
      

      *这不是真正的内存泄漏,但有些人说“内存泄漏”的意思是“内存不足”。在任何情况下,堆栈空间都比堆空间更有限,所以你必须注意你在那里使用的内存块的大小。

      【讨论】:

      • 即使递归调用也不会造成内存泄漏(递归中可能存在导致内存不足的错误,但我不会将其描述为“泄漏” ,本身)​​。
      • 没错,但有时人们说“内存泄漏”的意思是“我的内存不足”
      • 这个数组可能在一个类中,如果这个类被泄露,那么整个数组就会被泄露。根据 OP 使用的工具,事情可能会令人困惑。
      • 是的,OP 知道 std::string,所以可能听说过 malloc。
      【解决方案4】:

      澄清到目前为止给出的好的答案:

      • 是的,description[0]=0 从 strxxx 函数 POW 中清除字符串:strlen(description) == 0、strcmp(description, "") == 0 和 std::string(description) == "" 都是真的。

      • 不,description[0]=0 与 free(description) 或 memset(description, 0, sizeof description) 不同。但你已经知道了。

      • 您引用的那段代码不可能导致内存泄漏。内存不是在堆上分配的,内存泄漏是堆的事情。

      【讨论】:

        【解决方案5】:

        \0 放在字符串的第一个元素中是清除字符串的安全方法,但这与删除字符串不同,并且不会防止内存泄漏。

        【讨论】:

          【解决方案6】:

          如果是 char[] 字符串,并且对它执行的唯一操作是字符串函数,那很好。当然,这对于受保护的数据来说还不够好。

          至于内存泄漏,可能值得更改为字符串函数的安全版本,但您不能泄漏静态或基于堆栈的字符串,因此它可能是您的字符串被传递出去的地方。

          为清楚起见,我将其更改为 '\0'。

          【讨论】:

          • 我认为不能保证 NUL 字符 ('\0') 的值为零。使用 '\0' 不仅可以提高清晰度,还可以使您的代码可移植到所有那些非 ASCII 平台。您可能关心也可能不关心。
          • 我很确定,虽然 NUL 是特定于 ASCII 的,并且 null 可以是任何东西,只要它始终如此,'\0' 必须为零。
          • 该标准确实保证用于指示字符串结尾的空终止符是整数 0。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多