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
.