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
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;
}