使用指针实现 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";
您已经为 s1
和 s2
分配了 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
然后有内存泄漏,因为首先s1
和s2
被设置为分配内存的地址,然后它们被地址重新分配字符串文字的第一个字符。
此外,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" ) );
我正在阅读 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";
您已经为 s1
和 s2
分配了 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
然后有内存泄漏,因为首先s1
和s2
被设置为分配内存的地址,然后它们被地址重新分配字符串文字的第一个字符。
此外,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" ) );