Consider the following program
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct my_string{
int len;
char *buf;
} my_string_t;
my_string_t *init_my_string(char *);
my_string_t *call_init_my_string();
int main(int argc, char *argv[])
{
my_string_t *st1 = call_init_my_string();
printf("%d\n", st1->len);
printf("%s\n", st1->buf);
free(st1);
return 0;
}
my_string_t *call_init_my_string()
{
my_string_t *st1 = init_my_string("Foo");
return st1;
}
my_string_t *init_my_string(char *s)
{
my_string_t *st = (my_string_t *) malloc(sizeof(*st));
st->len = strlen(s);
st->buf = s;
return st;
}
The question is, does this program suppose to result in undefined behaviour or some kind of error? since the string "Foo"
inside function call_init_my_string
is locally declared and get passed to init_my_string
function. In init_my_string
function, I allocate a space to hold the size of of the string and the string itself, but as i know, this allocation my_string_t *st = (my_string_t *) malloc(sizeof(*st));
only allocate enough space for st->len
and st->buf
pointer and not for string "Foo"
since I only assign the string to st->buf
instead of allocating it first and then do like the following:
st->buf = (char *) malloc(strlen(s) + 1);
memcpy(st->buf, s, strlen(s));
st->buf[strlen(s)] ='\0';
But after I compile it and run, it gives me no errors and the program runs fine. why this program works fine and gives me no errors?
this is the result printed on the screen:
$ gcc struct_ptr_string1.c -o struct_ptr_string1
$ ./struct_ptr_string1
3
Foo
The "Foo" string is a constant string probably stored somewhere statically. What happens in init_my_string
is that you indeed allocate a new memory chunk, but you will assing st->buf
to s
which is the pointer which points to this "Foo" string. So you dont copy "Foo", but rather just set st->buf
to the location where it is stored.
my_string_t *init_my_string(char *s)
{
my_string_t *st = (my_string_t *) malloc(sizeof(*st));
printf("st address=%d\n", st);
printf("s address=%d\n", s);
st->len = strlen(s);
st->buf = s;
printf("st->buf address=%d\n", st->buf);
return st;
}
Output:
st address=19779600
s address=4196344
st->buf address=4196344
3
Foo
As you see st->buf
actually points to the constant string thats why no error.
There's no undefined behaviour in your code.
The string literal "Foo"
has static storage duration . You are passing its address to init_my_string
and simply store that address (essentially a pointer to "Foo"
).
Your code is equivalent to (except we have one more copy of "Foo"
):
my_string_t *call_init_my_string()
{
static char s[] = "Foo";
my_string_t *st1 = init_my_string(&s[0]);
return st1;
}
my_string_t *init_my_string(char *s)
{
my_string_t *st = malloc(sizeof(*st));
st->len = strlen(s);
st->buf = s;
return st;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.