簡體   English   中英

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函數中,我分配了一個空間來保存字符串的大小和字符串本身,但據我所知,這個分配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

“Foo”字符串是一個常量字符串,可能靜態存儲在某個地方。 init_my_string發生的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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM