Home > Back-end >  why malloc() changes char pointers own address
why malloc() changes char pointers own address

Time:02-17

I want to write a function that can take a destination pointer to allocate memory and copy a source into it.

If I try to allocate memory inside the function for the the destination, char *dest inside the function gets a complete new address and I mean the address of the pointer itself.

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

void ownStrCpy(char *dest, char *src){
    printf("%p = address inside ptr variable c inside function before malloc\n", dest);

    dest = (char*)malloc(strlen(src)*sizeof(char) 1);

    printf("%p = address inside ptr variable c inside function after malloc\n", dest);
    printf("%p = address from ptr variable c inside function after malloc\n", &dest);

    for(int i=0; i < strlen(src); i  ){
        dest[i] = src[i];
    }
    dest[strlen(src) 1] = '\0';
}

int main()
{

    char *c;
    char a = 'a';
    //c = NULL;
    c = &a;
    printf("%p = address from variable a\n", &a);
    printf("%p = address from ptr variable c\n", &c);
    printf("%p = address inside ptr variable c\n", c);

    ownStrCpy(c, "Example String");

    printf("%p = address inside ptr variable c after function call\n", c);

    char *c2;
    printf("\n%p = address from variable c2\n", &c2);
    printf("%p = address inside ptr variable c2\n", c2);
    c2 = (char*)malloc(10*sizeof(char) 1);
    printf("%p = address inside ptr variable c2\n", c2);
    printf("%p = address from ptr variable c2 after malloc\n", &c2);

    //free(c);
    free(c2);

    return 0;
}

and that is the output.

000000000061FE17 = address from variable a
000000000061FE18 = address from ptr variable c
000000000061FE17 = address inside ptr variable c
000000000061FE17 = address inside ptr variable c inside function before malloc
0000000000A46E30 = address inside ptr variable c inside function after malloc
000000000061FDE0 = address from ptr variable c inside function after malloc
000000000061FE17 = address inside ptr variable c after function call

000000000061FE08 = address from variable c2
000000000000003E = address inside ptr variable c2
0000000000A46E50 = address inside ptr variable c2
000000000061FE08 = address from ptr variable c2 after malloc

As you can see, 'the address from ptr variable c inside function after malloc' has changed to a address that is not existing?

I tried to change how I hand over the pointer to the function, tried a double pointer, tried accessing the pointer inside the function differently but nothing worked.

I know that I can return the pointer to the pointer variable 'c' in the main function but that is not what I want. Where is the difference to the part inside of the main function where it stays the same after calling malloc() for c2?

CodePudding user response:

A pointer is just a number. Consider this:

int dest = 123;
dest = 456;

dest will be 456.

Now consider this.

char *c;
char a = 'a';
c = &a;
char *dest = c;
dest = malloc(10);

Will dest contain &a? No, it will contain the result of malloc.

That's what ownStrCpy is doing. It immediately overwrites dest with the contents of malloc.


You can do what you want with a double pointer.

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

void ownStrCpy(char **dest, const char *src) {
    size_t len = strlen(src);

    // Allocate new memory.
    // char is defined to be sizeof 1
    // don't cast the result of malloc
    char *copy = malloc(len 1);

    // Copy to the new memory.
    for(int i=0; i <= len; i  ) {
        copy[i] = src[i];
    }
    copy[len 1] = '\0';

    // `dest` points at c.
    // `*dest` is the value of c, currently `&a`.
    // `*dest = copy` changes the value of `c` to `copy`.
    *dest = copy;
}

int main() {
    char *c;
    char a = 'a';
    c = &a;

    ownStrCpy(&c, "Example String");

    printf("c = %s", c);
}

By passing in &c you can change the value of c inside ownStrCpy.

However, if you're going to allocate new memory inside a function, just return the new pointer.

char *ownStrCpy(const char *src) {
    size_t len = strlen(src);

    // Allocate new memory.
    // char is defined to be sizeof 1
    // don't cast the result of malloc
    char *copy = malloc(len 1);

    // Copy to the new memory.
    for(int i=0; i <= len; i  ) {
        copy[i] = src[i];
    }
    copy[len 1] = '\0';

    return copy;
}

int main() {
    char *c;
    char a = 'a';
    c = &a;

    c = ownStrCpy("Example String");

    printf("c = %s", c);
}

And you've just implemented strdup.

  • Related