C:用指针缺少一些逻辑

时间:2010-01-29 19:17:00

标签: c string pointers memory-management c-strings

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

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

我无法理解为什么......在被调用函数内部分配内存是错误的吗?

5 个答案:

答案 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);。不漂亮。