使用指针实现strcat()

时间:2015-12-15 18:22:23

标签: c pointers kernighan-and-ritchie

我正在阅读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;
}

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

6 个答案:

答案 0 :(得分:6)

问题在于:

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

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

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

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

现在您正在使用分配的空间。 希望这会有所帮助。

编辑:你在这里也有问题:

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

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

答案 1 :(得分:1)

s1 = "Hello ";

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

尝试改为strcpy(s1, "Hello ");

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

您无法通过简单的作业复制字符串。

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

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

直接分配不适用于数组。

“Hello”本质上是一个char数组。

另外,就像有人在评论中所说,“Hello”是在代码的只读部分中分配的(因为它是在编译期间分配的),所以当你使用你的作业时,你实际上将s1重定向到只读位置,当你尝试在只读位置写字时,你的时间会很糟糕。

答案 4 :(得分:1)

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

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

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

    return p;
}

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

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

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

您可以改为编写

int size = 1024;
char *s;

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

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

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

甚至你可以写一行

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

答案 5 :(得分:0)

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

// 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。{/ p>