strcpy()/strncpy() crashes on structure member with extra space when optimization is turned on on Unix?

前端 未结 6 1508
再見小時候
再見小時候 2021-02-06 23:34

When writing a project, I ran into a strange issue.

This is the minimal code I managed to write to recreate the issue. I am intentionally storing an actual string in the

6条回答
  •  囚心锁ツ
    2021-02-06 23:50

    What you are doing is undefined behavior.

    The compiler is allowed to assume that you will never use more than sizeof int64_t for the variable member int64_t c. So if you try to write more than sizeof int64_t(aka sizeof c) on c, you will have an out-of-bounds problem in your code. This is the case because sizeof "aaaaaaaa" > sizeof int64_t.

    The point is, even if you allocate the correct memory size using malloc(), the compiler is allowed to assume you will never use more than sizeof int64_t in your strcpy() or memcpy() call. Because you send the address of c (aka int64_t c).

    TL;DR: You are trying to copy 9 bytes to a type consisting of 8 bytes (we suppose that a byte is an octet). (From @Kcvin)

    If you want something similar use flexible array members from C99:

    #include 
    #include 
    #include 
    
    typedef struct {
      size_t size;
      char str[];
    } string;
    
    int main(void) {
      char str[] = "aaaaaaaa";
      size_t len_str = strlen(str);
      string *p = malloc(sizeof *p + len_str + 1);
      if (!p) {
        return 1;
      }
      p->size = len_str;
      strcpy(p->str, str);
      puts(p->str);
      strncpy(p->str, str, len_str + 1);
      puts(p->str);
      memcpy(p->str, str, len_str + 1);
      puts(p->str);
      free(p);
    }
    

    Note: For standard quote please refer to this answer.

提交回复
热议问题