在函数调用中作为参数初始化的结构成员char*

在函数调用中作为参数初始化的结构成员char*,c,pointers,C,Pointers,这更多的是出于好奇,而不是我想要或需要它如何工作。但当我做一些模型,想测试一些东西,我最终得到了这样的东西。。。我想知道为什么它不能像我预期的那样工作 typedef struct { char *a; char *b; char *c; }mystruct; void init_chars (char *arg) { arg = malloc (sizeof (char)*10); arg = "0123456789"; printf ("%s

这更多的是出于好奇,而不是我想要或需要它如何工作。但当我做一些模型,想测试一些东西,我最终得到了这样的东西。。。我想知道为什么它不能像我预期的那样工作

typedef struct {
    char *a;
    char *b;
    char *c;
}mystruct;

void init_chars (char *arg)
{
    arg = malloc (sizeof (char)*10);
    arg = "0123456789";
    printf ("%s\n", arg);
}

int main ()
{
    mystruct *msp = malloc (sizeof (mystruct));
    init_chars (msp->a);
    init_chars (msp->b);
    init_chars (msp->c);
    printf ("%s, %s, %s\n", msp->a, msp->b, msp->c);
    return 0;
}
印刷品

0123456789
0123456789
0123456789
(空)、(空)、(空)

在C语言中,当将值传递给函数参数时,有两件事

  • 传递值
  • 参照
  • 您正在按值传递,因此您正在向函数传递一些未初始化的值,并在函数中初始化它,而函数外部不可见。您正在尝试在
    main()
    中使用未初始化的值,这将导致未定义的行为

    arg = "0123456789";
    
    如果要将字符串复制到某个内存位置,则需要
    memcpy()
    strcpy()


    注意:使用未初始化的值会导致未定义的行为。

    您的代码有几个问题。以下是固定代码:

    arg = "0123456789";
    
    /* Don't forget to include <stdio.h>, <stdlib.h> and <string.h> */
    
    typedef struct {
        char *a;
        char *b;
        char *c;
    }mystruct;
    
    void init_chars (char **arg) /* This should be char** as the address of a char* is passed */
    {
        *arg = malloc ( /*sizeof(char)* */ 11); /* sizeof(char) is 1 always. You don't need it */
                                                /* Note the change of `arg` to `*arg` too */
                                                /* And that I've used 11 and not 10 because there needs to be space for the NUL-terminator */
    
        if(*arg == NULL) /* If the above malloc failed */
        {
            printf("Oops! malloc for *arg failed!");
            exit(-1);
        }
    
        //arg = "0123456789"; /* You just lost the allocated memory as you make the pointer point to a string literal */
    
        strcpy(*arg, "0123456789"); /* Use strcpy instead */
        printf ("%s\n", *arg);      /* *arg here */
    }
    
    int main ()
    {
        mystruct *msp = malloc (sizeof (mystruct));
    
        if(msp == NULL) /* If the above malloc failed */
        {
            printf("Oops! malloc for msp failed!");
            return -1;
        }
    
        init_chars (&(msp->a));
        init_chars (&(msp->b)); 
        init_chars (&(msp->c));  /* Pass address of variables rather than their value */
    
        printf ("%s, %s, %s\n", msp->a, msp->b, msp->c);
    
        free(msp->a);
        free(msp->b);
        free(msp->c);
    
        free(msp);    /* Free everything after use */
    
        return 0;
    }
    
    /*不要忘记包括,以及*/
    类型定义结构{
    char*a;
    char*b;
    char*c;
    }我的结构;
    void init_chars(char**arg)/*这应该是char**,因为传递了char*的地址*/
    {
    *arg=malloc(/*sizeof(char)**/11);/*sizeof(char)始终为1。您不需要它*/
    /*请注意将'arg'更改为'*arg'*/
    /*我用了11而不是10,因为NUL终结者需要空间*/
    如果(*arg==NULL)/*如果上述malloc失败*/
    {
    printf(“Oops!malloc for*arg失败!”);
    出口(-1);
    }
    //arg=“0123456789”/*当指针指向字符串文字时,您刚刚丢失了分配的内存*/
    strcpy(*arg,“0123456789”);/*请改用strcpy*/
    printf(“%s\n”,*arg);/**此处arg*/
    }
    int main()
    {
    mystruct*msp=malloc(sizeof(mystruct));
    如果(msp==NULL)/*如果上述malloc失败*/
    {
    printf(“Oops!msp的malloc失败!”);
    返回-1;
    }
    初始字符(&(msp->a));
    初始字符(&(msp->b));
    init_chars(&(msp->c));/*传递变量的地址,而不是它们的值*/
    printf(“%s,%s,%s\n”,msp->a,msp->b,msp->c);
    免费(msp->a);
    免费(msp->b);
    免费(msp->c);
    免费(msp);/*使用后免费*/
    返回0;
    }
    
    输出:

    0123456789

    0123456789

    0123456789

    012345678901234567890123456789


    与您的代码进行比较,您将了解为什么要将
    a
    b
    c
    的副本传递给
    初始化\u chars
    ,这很好地分配了内存,将指针存储在
    arg
    变量中,该变量在函数返回时不再存在,因此,在不修改原始
    a
    b
    c
    的情况下泄漏内存,将指针传递到未初始化的值是不正确的。但是
    return
    不是更好的建议吗?@Potatoswatter我只是把它作为一个注释,以确保OP理解未初始化的值会导致UB1)您没有释放分配的内存,导致内存泄漏;2)您使用
    *arg=“0123456789”丢失了最近分配的内存。是的,你是对的,我会修理它。您的代码是安全和清晰的您没有为NUL终止符分配空间(
    '\0'
    )。因此,
    strcpy
    行写入一个无效的内存位置,调用未定义的行为。哦,我忘了,非常感谢。如果malloc失败,我应该检查(*arg==NULL)。