使用指针实现 strcat()

Implementing strcat() using pointers

我正在阅读 K&R 并尝试进行涉及使用指针编写一个版本的 strcat(将一个字符串附加到另一个字符串的末尾)的练习。这就是我所拥有的:

#include<stdio.h>
void mystrcat(char *s,char *t)
{
    while(*s++);
    *s--;
    while(*s++ = *t++);
}

int main()
{
    int size = 1024;
    char *s1, *s2;
    s1 = malloc(size);
    s2 = malloc(size);
    s1 = "Hello ";
    s2 = "World";
    mystrcat(s1,s2);
    printf("%s",s1);
    return 0;
}

程序运行直接崩溃,对指针不是很熟悉所以无法解决错误。

问题出在这里:

s1 = malloc(size);
s2 = malloc(size);
s1 = "Hello ";
s2 = "World";

您已经为 s1s2 分配了 space,但您没有使用它,而是让它们指向字符串文字。这些字符串文字存储在内存的不可写位置(即,你不应该弄乱它)。

简而言之,您必须将代码更改为:

s1 = malloc(size);
s2 = malloc(size);
strcpy( s1, "Hello " );
strcpy( s2, "World" );

现在您正在使用分配的space。 希望这有帮助。

编辑:你这里也有问题:

void mystrcat(char *s,char *t)
{
    while(*s++);
    *s--;
    while(*s++ = *t++);
}

第二行应该是s--,而不是*s--*s-- 将减少指针 s 并访问该新位置。您实际上不需要取消引用指针只是为了减少它。您只希望指针在指向现在之前指向一个位置。就是 s--.

您为字符串分配了内存,但随后覆盖了它并丢失了对该内存的引用:

// allocate memory
s1 = malloc(size);
s2 = malloc(size);
// assign another address, e.g. lose the pointer
s1 = "Hello ";
s2 = "World";

您应该将字符串复制到分配的内存中:

// allocate memory
s1 = malloc(size);
s2 = malloc(size);
// copy the string into it
strcpy(s1, "Hello ");
strcpy(s2, "World");

此外,在使用完毕后始终free分配内存是一个好习惯。

s1 = "Hello ";

现在 s1 指向存储文字 "Hello " 的 7 个字符的只读数组。您丢失了指向 s1 之前指向的分配的 1024 个字符的指针。因此,您尝试附加到 s1 是非法的。

试试 strcpy(s1, "Hello ");

您在 *s-- 中又犯了一个错误。指针 s 超出缓冲区,您不应该取消引用它。

void mystrcat(char *s,char *t)
{
    while(*s++);
    s--;
    while(*s++ = *t++);
}

不能通过简单的赋值来复制字符串。

如果要将"Hello "复制到用malloc分配的内存中,则需要将字符串复制到该内存块中:

s1 = malloc(size);
s2 = malloc(size);
strcpy(s1, "Hello ");
strcpy(s2, "World");

直接赋值不适用于数组。

"Hello "本质上是一个字符数组。

此外,就像有人在评论中说的那样,"Hello " 分配在代码的只读部分(因为它是在编译时分配的),所以当你使用你的分配时,你实际上将 s1 重定向到一个只读位置,当您尝试在一个只读位置写入时,您会遇到麻烦。

首先,如果按以下方式定义函数会更好看

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

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

    return p;
}

标准 C 函数 strcat returns 指向目标字符串的指针。

至于main然后有内存泄漏,因为首先s1s2被设置为分配内存的地址,然后它们被地址重新分配字符串文字的第一个字符。

此外,C 和 C++ 中的字符串文字是不可变的。任何修改字符串文字的尝试都会导致程序出现未定义的行为。

你可以改写

int size = 1024;
char *s;

s = malloc(size);
s[0] = '[=11=]';

mystrcat( s, "Hello " );
mystrcat( s, "World" );

printf( "\"%s\"\n", s );

或者你甚至可以写成一行

printf( "\"%s\"\n", mystrcat( mystrcat( s, "Hello " ), "World" ) );