0

我正在编写自己的字符串复制函数。以下作品:

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);
}

我不明白为什么......在被调用函数中分配内存是一个错误吗?

4

5 回答 5

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
}

请记住,如果长度小于源缓冲区的实际长度,您将超出目标缓冲区。请参阅评论以获取解决方案,尽管这取决于您。

于 2010-01-29T19:21:48.433 回答
2

在函数内部分配没有问题。

问题是在 C 中参数是按值传递的。因此,当您将值分配给 dest 时,这只是修改函数的本地 dest。

你有两个选择。您可以返回 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;
}

不需要使用局部变量的技术,但我认为它使代码更具可读性。

于 2010-01-29T19:21:58.327 回答
2

在函数内部执行 malloc 是可以的,但您没有将指针传回函数之外。要么返回指针:

char * mystringcopy(char *src)

或将指针传递给指针:

void mystringcopy(char *src, char **dest)
于 2010-01-29T19:22:05.297 回答
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
于 2010-01-29T19:23:20.223 回答
1

一般来说,在分配内存时,有一些关于什么代码在完成后负责释放内存的假设。我赞同一个功能应该负责一个主要操作的概念,就像一个黑匣子一样。出于这两个原因,最好分配您自己的内存并将指针交给函数以填充其缓冲区。

除此之外,您可以将char *指针作为返回值返回。

或者,将char *dest参数更改为char **dest。然后,像这样调用函数:mystringcopy(src, strlen(src), *dest). 在函数中,它通过以下方式返回指针:*dest = (char *)malloc(length + 1);。不漂亮。

于 2010-01-29T19:23:11.443 回答