将内存分配给作为函数内部参数的指针

Allocating memory to a pointer giving as argument inside a function

我想编写一个可以将一个 C 字符串的内容复制到另一个 C 字符串的函数。

#include <stdio.h>
#include <string.h>
void copy(char*,char*);
int main(){
    char* string = "hello";
    char* destination;

    copy(destination,string);
    printf("Source: %s\nDestination: %s",string,destination);

    system("pause");
    return 0;   
}
void copy(char* dest, char* src){
    dest = malloc(strlen(src)*sizeof(char)); //Crashes

    while (*src){
        *dest++ = *src++;
    }   
} 

在函数内部分配内存导致程序崩溃,而在函数调用起作用之前分配内存:

char* destination = malloc(strlen(string)*sizeof(char)); //works

问题是 copy 获取地址 - destination 的当前值和 source 的值。

然后用malloc的结果覆盖destination的当前值。

然后进行复制,malloced 内存丢失。

return 复制 destination 的值,而不是传入它。

或使用char **和*.

char * copy( char* src){
    char * dest = malloc( (1+strlen(src))*sizeof(char)); //Crashes
    char * toReturn = dest;

    while (*src){
        *dest++ = *src++;
    } 
  return toReturn;
} 

void copy( char ** dest, char* src){
     /* overwrite pointer value with the result of malloc */
    char * toCopy;
    (*dest) = malloc((1+strlen(src))*sizeof(char)); //Crashes
    toCopy = *dest;
    while (*src){
        *toCopy++ = *src++;
    } 
} 

在您的 main() 函数中,您声明了一个类型为 char * 的变量 destination 而没有对其进行初始化。然后将 destination 作为参数传递给 copy() 函数。了解传递给 copy() 的数据很重要。在这种情况下,由于 destination 尚未初始化,我们不知道传递给 copy() 的内容。当您在函数调用之前 malloc() 时,这很好,因为在那种情况下,destination 已被初始化。特别是,它的值是由 malloc().

返回的堆中的某个地址

正如其他人指出的那样,您还应该小心分配比 src 字符串长度多 1 个字节,以便允许 space 作为空终止符。

已通过多种不同方式解释的主要问题与如何将 dest 传递给 copy() 有关。当您将指针传递给函数时,例如:

void copy(char* dest, char* src) {

函数接收一个副本的指针,它将指向相同的地址,但将有自己的不同地址.所以当你传递 char *dest 时,copy() 函数接收到 dest 指针的 copy。当您在 copy() 中分配 dest 时,调用者 main() 不知道 destcopy() 中的地址是什么,也无法访问内存return由 dest = malloc(strlen(src)*sizeof(char));copy() 编辑。

每当你在一个函数中分配内存时,如果你没有returning新分配的内存块的地址,你必须通过address of 指向函数的指针(不是指针的副本)。这样,当您调用 malloc 时,您将 malloc 的 return(新内存块的起始地址)指定为指针 处的值与 main() 中相同的地址

如果您什么都不记得了,请记住这条规则:如果您要为传递给函数的指针分配内存,则必须 (1) return 调用方的新地址;或 (2) 将指针的地址传递给函数进行分配。

这是另一个采用类似思路但采用几种不同方法的示例:

#include <stdio.h>
#include <stdlib.h>

void copy (char **dest, char *src);

int main (int argc, char **argv) {

    char *str = argc > 1 ? argv[1] : 
                "A quick brown fox jumps over the lazy dog.";
    char *dest = NULL;

    copy (&dest, str);

    printf ("\n str  : %s\n dest : %s\n\n", str, dest);

    free (dest); /* free allocated memory */

    return 0;
}

void copy (char **dest, char *src)
{
    if (!src) {     /* validate src string */
        fprintf (stderr, "%s() error: invalid string 'src'.\n",
                __func__);
        return;
    }

    size_t len = 0;
    char *p = src;

    for (;*p; p++, len++) {}    /* strlen */

    /* allocate and validate -- every time */
    if (!(*dest = malloc (len * sizeof **dest + 1))) {
        fprintf (stderr, "%s() error: virtual memory exhausted.\n",
                __func__);
        exit (EXIT_FAILURE);
    }

    p = *dest;  /* copy src to dest */
    for (; *src; src++) *p++ = *src;
    *p = 0;     /* null-terminate   */
}

输出

$ ./bin/copystr

 str  : A quick brown fox jumps over the lazy dog.
 dest : A quick brown fox jumps over the lazy dog.

注意: 如果您不使用 gcc 然后将 __func__ 更改为函数名称。