0

我对以下功能有 3 个问题。我将它们标记为代码中的注释。

  1. 为什么我们将destmalloced memory)指向的char项复制到dPtr,然后在最后(处理输入字符串后)return dest。操作起来岂不是更简单dest

  2. 这个函数基本上只有在里面有破折号的情况下才会反转单词。标记的命令是否*subword = '\0';NUL字符放置在先前增加的位置(in strncpy) -subword+1subword

  3. 这个函数是否容易出现一些缓冲区溢出或其他不良行为?现在它没有给我任何错误,但我想我只是不知道如何调试它。


lenstrlen(word)

char* function(char* word, int len)
{
    char* subword = NULL;
    char* dest;
    char* dPtr;
    size_t n;

    dest = malloc(len+1);
    if (dest == NULL) return NULL;

    dPtr = dest;               /* [1] */

    while((subword = strrchr(word, '-'))!= NULL) {

        n = len - (subword-word) - (dPtr-dest);
        if (n-1 > 0)
            strncpy(dPtr, subword+1, n-1);

        *subword = '\0';      /* [2] */
        dPtr += n-1;
        *dPtr = '-';
        dPtr++;
    }
    strncpy(dPtr, word, len - (dPtr-dest));
    dest[len] = '\0';
    return dest;              /* [1] */
}
4

3 回答 3

1

为什么我们将dest(malloced memory)指向的char item复制到dPtr,然后最后(处理完输入字符串后)返回dest。在dest上操作不是更简单吗?

因为在函数结束时,dPtr不会指向dest字符串的开头,所以如果该指针是dest它本身,我们就不会返回我们构建的整个目标字符串。

于 2012-08-31T15:53:52.127 回答
1
  1. 如果dest直接修改,函数返回的值就不一样了。所以你需要通过一个临时指针。
  2. \0字符被放置在*subword(而不是字符-)的位置。
于 2012-08-31T15:55:58.113 回答
1
  1. dPtr用于在字符串中移动并对其进行修改。dest被保留为修改后的字符串的开头,最终是函数的返回值。在每次循环迭代结束时,dPtr将指向修改字符串的结尾,并用于每个连续的strncpy. 最终,该函数返回一个修改后的字符串,并且dest需要跟踪它的开始。

  2. subword大概是空终止的,因此只有字符 insubword将被复制到strncpy循环内的结果中,但这实际上对于使用strncpy. 该函数在字符串中向后移动以查找破折号。对于每个命中,subword是下一个以破折号分隔的子字符串。子字符串是原始字符串中的一块内存,它不是以空值结尾的。如果您正在使用,strcpy那么您需要空终止符subword,但是由于您使用strncpy的是空终止符,因此没有必要:只需注意将您的n值作为strncpy限​​制。此代码空终止subword 到位,即通过在原始字符串参数中粘贴空字符。这导致#3:

  3. 至于不希望的行为,该函数通过修改原始字符串参数来工作——它将那些空终止符subword放入源字符串中——即使它为修改和返回的字符串保留自己的缓冲区。

最后,代码可以不用dPtr操作strncat而不是strncpy.

于 2012-08-31T16:04:25.940 回答