首页 > 解决方案 > c程序没有给我错误

问题描述

考虑以下程序

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

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

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

但是在我编译并运行之后,它没有给我任何错误并且程序运行良好。为什么这个程序运行良好并且没有错误?

这是打印在屏幕上的结果:

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

3
Foo

标签: cpointersundefined-behaviorlocal-variables

解决方案


“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,实际上指向常量字符串,这就是为什么没有错误。


推荐阅读