【问题标题】:is memmove necessary for trim function in C?C 中的修剪功能需要 memmove 吗?
【发布时间】:2012-07-09 19:18:02
【问题描述】:

我正在阅读 wikipedia article on Trimming 并看到了 ltrim(左修剪)的实现

char *
ltrim(char *str)
{
  char *ptr;
  int  len;

  for (ptr = str; *ptr && isspace((int)*ptr); ++ptr);

  len = strlen(ptr);
  memmove(str, ptr, len + 1);

  return str;
}

如果我跳过 memmove 并返回 ptr istead 会发生不好的事情吗?

char *
ltrim(char *str)
{
  char *ptr;
  int  len;

  for (ptr = str; *ptr && isspace((int)*ptr); ++ptr);

  return ptr;
}

【问题讨论】:

    标签: c trim memmove


    【解决方案1】:

    如果你返回ptr——即,一个不同于原始指针的指针值——并且如果该指针是指向原始内存块的唯一指针,那么没有人能够free()它,并且会有内存泄漏。您不能在指向已分配块中间的指针上调用 free(),而只能在指向块开头的指针上调用 - 即,只能在最初由 malloc() 返回的指针上调用。

    如果出于某种原因您可以确定指向原始块的指针将被保留,或者永远不需要释放该块,则不需要memmove();但对于通用实用程序例程,这些假设是错误的。

    【讨论】:

    • 既然它改变了原始指针的内容并返回原始指针......我相信返回类型应该是void。否则会产生误导。
    • @trinithis -- 我不知道。能够写出类似char * ptr = ltrim(rtrim(getline())) 的东西怎么样?
    【解决方案2】:

    最大的问题:这不是 ltrim() 预期的工作方式。

    ltrim() 预计会有副作用,将字符串原地更改

    例如,

    char *a = " hello";
    trim(a);
    printf(a);
    

    预计会打印"hello",但如果没有memmove(),则不会。

    编辑添加:

    下面的评论合理地问:“预计由谁?

    在具有自动垃圾收集功能的语言中,我希望字符串函数返回具有所需转换的 new 字符串。

    对于那些没有它的人(这里就是这种情况),我希望他们就地更改字符串,有时会返回指向结果的指针,有时不会。

    所以也许我应该说:这不是 C 函数所期望的工作方式。

    【讨论】:

    • 期望由?它可能在某些语言中以这种方式工作,但在大多数语言中并非如此。 Here 是“ltrim C”的第一个 Google 搜索结果,其中显示的实现返回一个指向未修改原始数据的新指针。事实上,要在 C 中实现你的版本,参数必须是指针到指针到字符,所以它甚至不能像你上面显示的那样被调用,事实上你不能不把它称为右值将是一个巨大的痛苦。
    • 我不明白 Ernest 的说法,即参数必须是指针到指针到字符。如果输入字符串没有被ltrim 修改,那么对ltrim 的调用可以很容易地被一个简单的s += strspn (s, " \t\f\r\n") ; 替换为你想要的任何字符作为空格。
    • 换句话说,您是说memmove() 确实是必需的——明确说明这一点会有所帮助。
    • @ErnestFriedman-Hill - 啊,现在我明白你在问什么了。我想是固定的。
    猜你喜欢
    • 2012-02-19
    • 1970-01-01
    • 2017-01-08
    • 2020-08-19
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多