Home > other >  Why can't I malloc request memory and assign a value in a function using a string, but a string
Why can't I malloc request memory and assign a value in a function using a string, but a string

Time:11-11

why it wrong `

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

void func(char* dest, const char* src)
{
    dest = malloc(strlen(src)   1);
    strcpy(dest, src);
}

int main()
{
    char* name0;
    char* name1 = "Jam";

    func(name0, name1);
    puts(name0);
    
    free(name0);
    return 0;
}

but

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

struct st
{
    char* name;
};

void func(struct st* st1, const struct st* st2);

int main(void)
{
    struct st name0, name1;
    name1.name = "Jam";

    func(&name0, &name1);

    puts(name0.name);

    free(name0.name);
    name0.name = NULL;

    exit(0);
}

void changename(struct st* st1, const struct st* st2)
{
    st1->name = malloc(strlen(st2->name)   1);
    if(st1->name == NULL)
        exit(1);
    strcpy(st1->name, st2->name);
}


` is right

#I tried to use the first method to explain why the second method makes sense and why the second method solves the problem, but the first one reports an error and doesn't give me the answer I want. #Why can't I malloc request memory and assign a value in a function using a string, but a string in a struct can?

CodePudding user response:

Try passing the pointer to the character pointer by reference not by value.

void func(char** dest, const char* src)
{
    *dest = malloc(strlen(src)   1);
    strcpy(*dest, src);
}

CodePudding user response:

Other errors that might be present aside, the big difference between those two is an additional level of indirection.

Consider this struct

struct foo { 
     int * x;
};

And now this two functions:

void f1(int* a) {  a = nullptr; }

void f2(foo* f) { f.x. = nullptr;  f = nullptr;}

When f1 is called, modifying the local copy a has no effect on the pointer passed by the caller:

int i = 0;
int* ptr = &i;
f1(ptr);                // a copy of ptr is made
assert( ptr == &i);     // ptr still points to i     

The same is true for the pointer passed to f2. Modifying f inside f2 has no effect on the pointer passed by the caller. Though, you can modify what f points to in f2, and that is visible to the caller.

foo fo;
int i = 0;
fo.x = &i;
foo* foptr = &fo;
f2(foptr);           // a copy of foptr is made, it also points to fo

assert( fo.x == nullptr);     // the function did modif fo
assert( foptr->x == nullptr); 

assert( foptr == &fo );       // same as above, foptr still points to fo
  • Related