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

前端 未结 6 1536
再見小時候
再見小時候 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:39

    why making things complicated? Overcomplexifying like you're doing gives just more space for undefined behaviour, in that part:

    memcpy((char*)&p->c, str, strlen(str)+1);
    puts((char*)&p->c);
    

    warning: passing argument 1 of 'puts' from incompatible pointer ty pe [-Wincompatible-pointer-types] puts(&p->c);

    you're clearly ending up in an unallocated memory area or somewhere writable if you're lucky...

    Optimizing or not may change the values of the addresses, and it may work (since the addresses match), or not. You just cannot do what you want to do (basically lying to the compiler)

    I would:

    • allocate just what's needed for the struct, don't take the length of the string inside into account, it's useless
    • don't use gets as it's unsafe and obsolescent
    • use strdup instead of the bug-prone memcpy code you're using since you're handling strings. strdup won't forget to allocate the nul-terminator, and will set it in the target for you.
    • don't forget to free the duplicated string
    • read the warnings, put(&p->c) is undefined behaviour

    test.c:19:10: warning: passing argument 1 of 'puts' from incompatible pointer ty pe [-Wincompatible-pointer-types] puts(&p->c);

    My proposal

    int main(){
        pack *p = malloc(sizeof(pack));
        char str[1024];
        fgets(str,sizeof(str),stdin);
        p->c = strdup(str);
        puts(p->c);
        free(p->c);
        free(p);
      return 0;
    }
    

提交回复
热议问题