禁用特定编译器优化

Ede*_*nia 2 c compiler-construction optimization

我使用C :: B在Win7的MinGW的gcc上编译了以下测试代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* Func. prototype */
char* returnString (void *str);

int main()
{
    printf("%s", returnString("Hello World!!!!!!!!!!!!"));

    return 1;
}

char* returnString (void *str)
{
    char *local = malloc(strlen((char*)str));

    strcpy(local, (char*)str);

    return local;
}
Run Code Online (Sandbox Code Playgroud)

默认情况下,分配会导致泄漏/ u/b ..因为我必须分配+1空终结符所在的一个空闲字节.但它不是导致泄漏或崩溃,而是像null终止一样工作.有什么方法可以解决这个问题吗?..而不是通过5543行代码+1使用.

Pas*_*uoq 5

下面的行导致缓冲区溢出,因为+ 1先前计算了要分配的大小时丢失了.

    strcpy(local, (char*)str);
Run Code Online (Sandbox Code Playgroud)

缓冲区溢出比内存泄漏严重得多.不幸的是,缓冲区溢出不会系统地崩溃程序.它调用未定义的行为,这意味着任何事情都可能发生,包括程序继续,就像你已经分配了足够大的集团一样.这不是编译器优化:它可以在任何优化级别发生(或不发生),并且程序员几乎无法控制发生的情况.请参阅下面的部分解决方案.


获取许多缓冲区溢出的诊断消息的一种方法是使用Valgrind在正常编译后执行程序.

或者,Clang和GCC的最新版本包含一个"地址清理程序"功能,通过激活-fsanitize=address,在生成的代码中插入一些可能检测到问题的指令.我没有使用此功能,但文档可用.

  • 海报的代码实际上导致缓冲区溢出和内存泄漏. (3认同)
  • @Edenia C中的缓冲区溢出是未定义的行为.它不必导致崩溃.不造成崩溃不是优化,只是运气不好.没有简单的选项可以告诉GCC生成一个崩溃所有未定义行为的程序,但是看看地址清理程序功能是否正在寻找(对于GCC 4.8或更高版本,`-fsanitize = address`). (2认同)