gpt4 book ai didi

strcpy 的 C 实现不改变变量值

转载 作者:行者123 更新时间:2023-11-30 20:05:47 25 4
gpt4 key购买 nike

所以,我正在尝试实现我自己的 strcpy 以更好地理解指针在 C 中的工作原理,但到目前为止我还不知所措。我尝试了很多不同的方法,尝试使用网络上的代码作为我的基础,但即使这些也行不通。

我相信我可能在主方法上以错误的方式调用该函数。我将变量的指针传递给函数,以便函数可以更改变量的值,并且在函数调用时,我给出指针的地址,以便该方法可以获得正确的数据。至少我相信这就是它的工作原理,无论如何我都能理解。

以下是函数和方法调用:

函数调用:

void my_strcpy( char *dest, const char* src ) {

dest = malloc(sizeof(src));

while ( src != '\0' ) {
*dest = *src;
src++;
dest++;
}

}

主要:

int main () {

const char* s = "Hello World";
char* test = 'd';

my_strcpy( &test, &s ); // Suposed to change test form d to Hello World.
printf("Changed String: " );
printf( "%c", test );


return 0;
}

PS:我尝试使用 test 作为大于 s 的字符串来查看是否是内存分配问题,但似乎并非如此。非常感谢任何帮助,因为我已经被困在这个问题上几个小时了......

PS:我已经研究了如何更改变量的问题和示例,并且可以使用简单的 int 来完成此操作。但使用 char* 时我无法做到这一点。因此就有了这个帖子。如果问题相同,我深表歉意,但我只是无法理解我在这里做错了什么。请耐心等待我,因为我是 C 初学者。

最佳答案

关键点是参数被传递by value 在 C 中。

因此,调用函数永远不会看到形式参数的任何更改。

最后,你的my_strcpy行为不符合标准 strcpy (不使用 malloc 分配内存)。以及您对 malloc 的使用是错误的,因为 sizeof(src)总是sizeof(char*) (即 Linux/x86-64 上的 8)。

这是一个更好的版本:

 void my_strcpy( char *dest, const char* src ) {
while ( *src != '\0' ) {
*dest = *src;
src++;
dest++;
}
*dest = '\0'; // zero terminate the string
}

请注意 strcpy (和 my_strcpy )本质上是危险的,因为您可能有 buffer overflow (因此更频繁地使用strncpy)。一个典型的用例是

 char buf[80];
my_strcpy(buf, "hello I am here");

所以我们有本地内存(通常在调用堆栈上)并且我们复制到其中。如果文字字符串非常长(例如超过 80 个字符),就会出现缓冲区溢出。

顺便说一句,你的测试while(src != '\0')是非常错误的。指针与指向的值不同。您的错误测试通常会在 32 位计算机上循环十亿次,并且会在达到终止条件 src == NULL 之前崩溃。

也在实践中strcpy通常通过优化编译器来了解,如 GCC编译时甚至可能生成循环,而不是对标准函数的函数调用。

如果您在编译器中启用所有警告(您总是应该这样做),您的编译器可能会发现您的一些错误(例如 GCC ),因此编译例如与 gcc -Wall -Wextra -g (获取所有警告、更多警告以及调试信息)然后使用调试器 gdb逐步运行您的程序。

在实践中,如果可能的话,让函数返回指针,例如

 char* my_almost_strdup(const char*src) {
size_t ln = strlen(src);
char* newptr = malloc(ln+1);
if (!newptr) { perror("my_strdup"); exit(EXIT_FAILURE); };
strcpy (newptr, src);
return newptr;
}

这有点像标准 strdup除了我捕获内存不足错误情况(当 malloc 失败时)。在失败的情况下,通常只显示一些错误消息并退出,但您应该始终处理 malloc失败

了解更多关于C dynamic memory management的信息并记录您的内存约定(当函数通过 malloccalloc 等在堆中分配内存时...您需要记录谁负责释放它以及如何)。

害怕undefined behaviormemory leaks 。使用valgrind如果有的话。

详细了解 garbage collection (这是一个非常有用的术语和概念)。您可能想使用 Boehm conservative garbage collector 编写一些 C 程序(但使用 Boehm 的 GC 是整个程序的决定)。

在您的 main

 my_strcpy( &test, &s ); // VERY BAD

多次错误(由于缓冲区溢出而导致未定义的行为)。您应该传递能够包含字符串(包括其终止零字节)的内存区域的地址,并且第二个参数没有正确的类型( &schar** 而不是 const char* )。 p>

关于strcpy 的 C 实现不改变变量值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29443151/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com