我正在编写自己的字符串复制功能。以下作品:
char *src, *dest;
src = (char *) malloc(BUFFSIZE);
//Do something to fill the src
dest = (char *) malloc(strlen(src) + 1);
mystringcpy(src, dest);
void mystringcopy(char *src, char *dest) {
for(; (*dest = *src) != '\0'; ++src, +dest);
}
但这不起作用:
char *src, *dest;
src = (char *) malloc(BUFFSIZE);
//Do something to fill the src
mystringcpy(src, strlen(src), dest);
void mystringcopy(char *src, size_t length, char *dest) {
dest = (char *)malloc(length + 1);
for(; (*dest = *src) != '\0'; ++src, +dest);
}
我无法理解为什么......在被调用函数内部分配内存是错误的吗?
答案 0 :(得分:2)
你还没有真正说出“工作”意味着什么,但我假设你很困惑,为什么dest
没有被改为调用函数中的新内存。
原因是在mystringcopy
函数中,参数dest
是调用函数中指针dest
的副本。
然后,您将该副本分配给新缓冲区,执行复制,然后副本消失。原件没有变化。您需要将dest
作为指针(指针)传递。
另外,我假设你写了你在内存中所做的事情,因为它不应该按原样编译(调用函数中的错误取消引用)。这是固定代码:
char *src, *dest;
src = (char *)malloc(BUFFSIZE); // no dereference on src, it's a pointer
//Do something to fill the src
mystringcpy(src, strlen(src), &dest); // pass the address of dest
// take a pointer to a char*
void mystringcopy(char *src, size_t length, char **dest) {
// now you should dereference dest, to assign to
// the char* that was passed in
*dest = (char *)malloc(length + 1);
// for simplicity, make an auxiliary dest
char* destAux = *dest;
// and now the code is the same
for(; (*destAux = *src) != '\0'; ++src, ++destAux);
}
另一种方法是返回dest
指针:
char *src, *dest;
src = (char *)malloc(BUFFSIZE);
//Do something to fill the src
dest = mystringcpy(src, strlen(src)); // assign dest
char* mystringcopy(char *src, size_t length) {
char* dest = (char *)malloc(length + 1);
// for simplicity, make an auxiliary dest
char* destAux = dest;
for(; (*destAux = *src) != '\0'; ++src, ++destAux);
return dest; // give it back
}
请记住,如果长度小于源缓冲区的实际长度,则会超出目标缓冲区。请参阅解决方案的评论,但这取决于您。
答案 1 :(得分:2)
在函数内部分配没有问题。
问题在于C参数是按值传递的。所以当你为dest赋值时,那只是修改函数的dest local。
你有两个选择。您可以返回dest指针:
char *alloc_and_copy(const char *src, size_t length)
{
char *dest = malloc(length + 1);
... do your copying
return dest;
}
或者您可以传递指向参数的指针并修改指向的内容:
void alloc_and_copy(const char *src, size_t length, char **dest)
{
char *local_dest = malloc(length + 1);
... do your copying using local_dest
*dest = local_dest;
}
不需要使用局部变量的技术,但我认为它使代码更具可读性。
答案 2 :(得分:2)
在函数内部执行malloc是可以的,但是你没有将指针传回函数。返回指针:
char * mystringcopy(char *src)
或传递指向指针的指针:
void mystringcopy(char *src, char **dest)
答案 3 :(得分:2)
C中的参数按值传递,因此您的函数获取dest
指针的副本,用malloc
覆盖它然后丢弃它。试试这个:
void mystringcopy(char *src, size_t length, char **dest) {
*dest = (char *)malloc(length + 1);
char *p=*dest;
for(; (*p = *src) != '\0'; ++src, ++p);
}
现在您传递一个指向字符串指针的指针,因此您可以在主过程中覆盖它。你会像以下一样使用它:
char *src, *dest;
*src = (char *) malloc(BUFFSIZE);
//Do something to fill the src
mystringcpy(src, strlen(src), &dest);
// now in dest you have your copy
答案 4 :(得分:1)
通常,在分配内存时,有一些关于什么代码在完成时释放内存的代码的假设。我赞成一个函数应该负责一个主要操作的概念,就好像一个黑盒子。出于这两个原因,最好分配自己的内存并将指针指向函数以填充其缓冲区。
除此之外,您可以将char *
指针作为返回值返回。
或者,将char *dest
参数更改为char **dest
。然后,调用函数:mystringcopy(src, strlen(src), *dest)
。在函数中,它返回指针:*dest = (char *)malloc(length + 1);
。不漂亮。