c程序没有给我错误

c program doesn't give me errors

考虑以下程序

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

问题是, 该程序是否会导致未定义的行为或某种错误? 因为函数 call_init_my_string 中的字符串 "Foo" 是在本地声明的 并传递给 init_my_string 函数。在 init_my_string 函数中,我分配 a space 来保存字符串的大小和字符串本身,但据我所知,这 分配 my_string_t *st = (my_string_t *) malloc(sizeof(*st)); 只分配足够 space 给 st->lenst->buf 指针而不是字符串 "Foo" 因为我只分配字符串 到 st->buf 而不是先分配它然后像下面这样:

 st->buf = (char *) malloc(strlen(s) + 1);
 memcpy(st->buf, s, strlen(s));
 st->buf[strlen(s)] ='[=11=]';

但是在我编译它并 运行 之后,它没有给我任何错误并且程序 运行 没问题。 为什么这个程序工作正常并且没有给我任何错误?

这是屏幕上打印的结果:

$ gcc struct_ptr_string1.c -o struct_ptr_string1
$ ./struct_ptr_string1

3
Foo

"Foo" 字符串是一个可能静态存储在某处的常量字符串。 init_my_string 中发生的事情是您确实分配了一个新的内存块,但是您会将 st->buf 分配给 s,这是指向此 "Foo" 字符串的指针。所以你不复制 "Foo",而是将 st->buf 设置到它存储的位置。

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

输出:

st address=19779600                                                                                                                                                                
s address=4196344                                                                                                                                                                  
st->buf address=4196344                                                                                                                                                            
3                                                                                                                                                                                  
Foo  

如您所见,st->buf 实际上指向常量字符串,这就是为什么没有错误。

您的代码中没有未定义的行为。

字符串文字 "Foo" 具有 静态存储持续时间 。您将其地址传递给 init_my_string 并简单地存储该地址(本质上是指向 "Foo" 的指针)。

您的代码等同于(除了我们还有一份 "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;
}