微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

strcat() 实现,如何重新分配足够的空间以在 C 中包含两个字符串?

如何解决strcat() 实现,如何重新分配足够的空间以在 C 中包含两个字符串?

我正在尝试使用指针自己实现 strcat 函数

我的伪代码是:

  • 接收 2 个字符指针(这意味着 2 个字符串(= 2 个字符数组))。
  • 创建 dest 数组的副本
  • dest
  • realloc() 空间是 source string + dest string 大小的总和,因为我需要 dest 字符串包含在两个字符串的末尾。
  • 创建一个指向 dest 字符串第一个索引的指针,该指针将作为函数的返回值返回。
  • whilesource 字符串上运行 2 个简单的 copy of dest 循环,并在执行此操作时将所有内容复制到 dest
  • 释放所有分配的指针
  • 返回指向 dest 字符串第一个索引的地址,方法是返回为此确切目的而创建的指针。

所以。我是这样写的:

char *StrCat(char *dest,const char *src)
{
   size_t size = strlen(dest) + strlen(src) + 1;
   char *temp = (char *) malloc(strlen(dest) + 1);
   char *start = dest;
   dest = (char *) realloc(dest,size);
   strcpy(temp,dest);
   while (*src)
   {
       *dest = *src;
       src++;
       dest++;
   }
   while (*temp)
   {
       *dest = *temp;
       temp++;
       dest++;
   }
   *dest = '\0';
   free(temp);
   return start;
}

void strcattest()
{
   char source[] = "this is source of cat";
   char dest4[100] = "this is dest of cat";
   StrCat(dest4,source);
   puts(dest4);
}

我得到: realloc(): invalid pointer.

我知道在 Internet 和 strcat 上有很多有效和更好的 stackoverflow 实现,但我在这里的目的是了解我做错了什么以及为什么我未能创建工作实施。 我对 starcat() 的理解出了什么问题?

解决方法

请注意,您只能在先前已分配的指针上使用 realloc,而不能在指向自动或静态存储数组的指针上使用。

所以这些行足以导致错误:

char *StrCat(char *dest,const char *src)
{
...
   dest = (char *) realloc(dest,size);
...
   char dest4[100] = "this is dest of cat";
   StrCat(dest4,source);

这就是标准库不尝试重新分配的原因...

,

来自 C 标准(7.23.3.1 strcat 函数)

2 strcat 函数附加了 s2 指向的字符串的副本 (包括终止空字符)到字符串的末尾 由 s1 指向。 s2的首字母覆盖null s1 末尾的字符。如果复制发生在对象之间 重叠,行为未定义。

因此在标准 C 字符串函数 strcat 中,不存在分配或重新分配内存。目标字符数组最初应足够大,以在其内部再容纳一个字符串。

考虑到您需要重命名函数。否则你的函数和标准函数会发生冲突。

函数定义可以如下(不使用任何标准字符串函数)

char * new_strcat( char *s1,const char *s2 )
{
    char *p = s1;

    while ( *p ) ++p;

    while ( ( *p++ = *s2++ ) );

    return s1;
}

这是一个演示程序。

#include <stdio.h>

char * new_strcat( char *s1,const char *s2 )
{
    char *p = s1;

    while ( *p ) ++p;

    while ( ( *p++ = *s2++ ) );

    return s1;
}

int main(void) 
{
    char s1[14] = "Hello ";
    const char *s2 = "World!";
    
    puts ( new_strcat( s1,s2 ) );
    
    return 0;
}

程序输出为

Hello World!

如果要编写一个新函数,将两个字符串组合起来创建一个新的字符数组(这样的函数与标准字符串函数 strcat 相比是一个不同的函数),则可以如下声明和定义该函数方式(在此实现中使用了标准字符串函数 strlen,尽管它可以不使用该函数来编写)。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char * combine( const char *s1,const char *s2 )
{
    char *result = malloc( strlen( s1 ) + strlen( s2 ) + 1 );
    
    if ( result )
    {
        char *p = result;
        
        while ( *s1 ) *p++ = *s1++;

        while ( ( *p++ = *s2++ ) );
    }
    
    return result;
}

int main(void) 
{
    const char *s1 = "Hello ";
    const char *s2 = "World!";
    
    char *p = combine( s1,s2 );
    
    if ( p ) puts( p );
    
    free( p );
    
    return 0;
}

再次程序输出是

Hello World!

至于你的功能,那么它是不正确的,没有任何意义。例如,用户可以将具有自动存储持续时间的字符数组传递给函数。您不能使用 realloc 动态重新分配它。

或者您首先将指针 start 分配给指针 dest 的值,但随后指针 dest 指向的内存被重新分配。因此,指针 start 具有从函数返回的无效值。

char *start = dest;
dest = (char *) realloc(dest,size);

//...
return start;

此外,您还尝试以相对于彼此的相反顺序复制字符串,首先您复制指针 src 指向的字符串,然后复制指针 {{ 最初指向的字符串1}}。 S0 您没有将第二个字符串附加到第一个字符串的尾部。

注意你的函数声明

dest

没有限定符char *StrCat(char *dest,const char *src); 的第一个参数表示指针const指向的字符串将被原地改变。因此,即使函数声明与您的函数实现相矛盾,因为您没有就地更改目标字符数组。您正在尝试创建一个新的字符数组。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。