如何更改 C 中预先存在的指针
How to change a preexisting pointer in C
我正在尝试创建一个 char* strcpy(char* dest, const char*) 函数。
这是我目前所拥有的:
char* mystrcpy(char *dest, const char *src)
{
char* tempsrc = (char*) src;
int length = strlen(src);
char tempdest[length];
for(int i = 0; i < length;i++)
{
tempdest[i]= tempsrc[i];
}
tempdest[length] = '[=10=]';
return dest = tempdest;
}
它return是正确的dest变量,所以可以在main方法中保存,但是如果return不保存,main方法中的*dest就不会保存像我希望的那样改变了。
如何更改 strcpy 中的 dest* 指针?
[编辑]
这是我用来测试这个的完整方法
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv){
char* source = "stringone";
char* dest = "stringtwo";
char* mystrcpy(char *dest, const char *src);
printf("Before src: %s\n", source);
printf("Before dest: %s\n", dest);
mystrcpy(dest, source);
printf("After src: %s\n", source);
printf("After dest: %s\n", dest);
}
char* mystrcpy(char *dest, const char *src)
{
int length = strlen(src);
for(int i = 0; i < length;i++)
{
printf("test\n");
dest[i] = src[i];
printf("test1\n");
}
dest[length] = '[=11=]';
return dest;
}
您正在做的是 return 指向局部变量的指针,即 tempdest
。当您从函数中 return 时,此变量超出范围,因此尝试取消引用该指针会调用 undefined behavior.
函数被赋予了一个要写入的目标缓冲区,因此只需直接写入它而不是单独的缓冲区。
char* mystrcpy(char *dest, const char *src)
{
int length = strlen(src);
for(int i = 0; i < length; i++)
{
dest[i] = src[i];
}
dest[length] = '[=10=]';
return dest;
}
如果另一方面的想法是创建一个新缓冲区并且 return 那,您需要通过 malloc
动态分配内存。您还需要为第一个参数传递 pointer-to-pointer,以便您可以更改调用函数中的指针值。
char* mystrcpy(char **dest, const char *src)
{
int length = strlen(src);
*dest = malloc(length+1);
if (*dest == NULL) {
perror("malloc failed");
exit(1);
}
for(int i = 0; i < length; i++)
{
(*dest)[i] = src[i];
}
(*dest)[length] = '[=11=]';
return *dest;
}
编辑:
你在第一个实现中出现段错误的原因是你没有传入字符数组,而是一个指向字符串文字的指针。字符串文字通常位于 read-only 内存区域,并且尝试写入(再次)未定义的行为。
您的目标缓冲区需要是一个大到足以存储您想要的字符串的可写数组。
char* source = "stringone";
char dest[50] = "stringtwo";
您在函数中更改 dest
,但更改不会传播到调用方。这是因为在 C 中参数是按值传递给函数的。
要获得 by-reference 风格的参数传递,您 "simply" 必须添加另一个间接级别。在您的情况下,这意味着:如果您想更改指针本身的值,则必须将指针传递给指针,即 pointer-pointer:
char* mystrcpy(char **dest, const char *src) // Another level of indirection
在函数内部您必须取消引用它:
*dest = tempdest;
但是,这将 return 指针,但它是无效的:*dest
然后指向 tempdest
指向的内容:局部变量。它在完成函数时失去了它的范围,所以在调用者的站点上它指向无主内存。您必须使用 malloc()
而不是本地内存来分配调用方站点上仍然可用的内存:
char *tempdest = malloc( length + 1); **
在调用方这边,你也必须添加间接寻址:
char *dest;
mystrcpy( &dest, src );
当然,当您不再需要内存时,您必须显式释放内存:
free(dest);
** length
是不够的,因为 strlen()
不算 [=21=]
终结符。但是你需要记忆。所以你必须加1.
我正在尝试创建一个 char* strcpy(char* dest, const char*) 函数。 这是我目前所拥有的:
char* mystrcpy(char *dest, const char *src)
{
char* tempsrc = (char*) src;
int length = strlen(src);
char tempdest[length];
for(int i = 0; i < length;i++)
{
tempdest[i]= tempsrc[i];
}
tempdest[length] = '[=10=]';
return dest = tempdest;
}
它return是正确的dest变量,所以可以在main方法中保存,但是如果return不保存,main方法中的*dest就不会保存像我希望的那样改变了。
如何更改 strcpy 中的 dest* 指针?
[编辑]
这是我用来测试这个的完整方法
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv){
char* source = "stringone";
char* dest = "stringtwo";
char* mystrcpy(char *dest, const char *src);
printf("Before src: %s\n", source);
printf("Before dest: %s\n", dest);
mystrcpy(dest, source);
printf("After src: %s\n", source);
printf("After dest: %s\n", dest);
}
char* mystrcpy(char *dest, const char *src)
{
int length = strlen(src);
for(int i = 0; i < length;i++)
{
printf("test\n");
dest[i] = src[i];
printf("test1\n");
}
dest[length] = '[=11=]';
return dest;
}
您正在做的是 return 指向局部变量的指针,即 tempdest
。当您从函数中 return 时,此变量超出范围,因此尝试取消引用该指针会调用 undefined behavior.
函数被赋予了一个要写入的目标缓冲区,因此只需直接写入它而不是单独的缓冲区。
char* mystrcpy(char *dest, const char *src)
{
int length = strlen(src);
for(int i = 0; i < length; i++)
{
dest[i] = src[i];
}
dest[length] = '[=10=]';
return dest;
}
如果另一方面的想法是创建一个新缓冲区并且 return 那,您需要通过 malloc
动态分配内存。您还需要为第一个参数传递 pointer-to-pointer,以便您可以更改调用函数中的指针值。
char* mystrcpy(char **dest, const char *src)
{
int length = strlen(src);
*dest = malloc(length+1);
if (*dest == NULL) {
perror("malloc failed");
exit(1);
}
for(int i = 0; i < length; i++)
{
(*dest)[i] = src[i];
}
(*dest)[length] = '[=11=]';
return *dest;
}
编辑:
你在第一个实现中出现段错误的原因是你没有传入字符数组,而是一个指向字符串文字的指针。字符串文字通常位于 read-only 内存区域,并且尝试写入(再次)未定义的行为。
您的目标缓冲区需要是一个大到足以存储您想要的字符串的可写数组。
char* source = "stringone";
char dest[50] = "stringtwo";
您在函数中更改 dest
,但更改不会传播到调用方。这是因为在 C 中参数是按值传递给函数的。
要获得 by-reference 风格的参数传递,您 "simply" 必须添加另一个间接级别。在您的情况下,这意味着:如果您想更改指针本身的值,则必须将指针传递给指针,即 pointer-pointer:
char* mystrcpy(char **dest, const char *src) // Another level of indirection
在函数内部您必须取消引用它:
*dest = tempdest;
但是,这将 return 指针,但它是无效的:*dest
然后指向 tempdest
指向的内容:局部变量。它在完成函数时失去了它的范围,所以在调用者的站点上它指向无主内存。您必须使用 malloc()
而不是本地内存来分配调用方站点上仍然可用的内存:
char *tempdest = malloc( length + 1); **
在调用方这边,你也必须添加间接寻址:
char *dest;
mystrcpy( &dest, src );
当然,当您不再需要内存时,您必须显式释放内存:
free(dest);
** length
是不够的,因为 strlen()
不算 [=21=]
终结符。但是你需要记忆。所以你必须加1.