I am running a simple C++ main program that has a leak in it. When I build this program through CMAKE Debug config and run it. It shows me the leak properly. But when I build this program with CMAKE Release config and run it. It says there is no leaks in the program.
**main.cpp**
#include <ios>
#include <iostream>
#include <fstream>
#include <string>
#include <chrono>
using namespace std;
using namespace std::chrono;
int main(int argc, char **argv) {
std::cout << "Hello, World!\n";
int *i = new int[10]; //leak generating code
int j = rand()%9;
std::cout<<"j="<<j<<std::endl;
if(j<0||j>9) return 0;
*(i+j) = 77;
std::cout<<"i="<<*(i+j)<<std::endl;
return 0;
}
**CMakeLists.txt**
cmake_minimum_required(VERSION 3.1)
project(leakTest)
set(CMAKE_BUILD_RPATH "$ORIGIN")
if (CMAKE_VERSION VERSION_LESS "3.1")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else ()
set (CMAKE_CXX_STANDARD 11)
endif ()
add_compile_options(-fsanitize=address)
add_link_options(-fsanitize=address)
add_executable(usingLeakTest main/src/main.cpp)
Cmake 3.8.x and 3.9.x used and tried out with C++11.
Can anyone explain or help in why this must be happening?
I am running the above code and CMAKE through CLION (Both Debug and release config). It is giving me proper Memory leak in the code with Debug build but with release build its giving me no leaks found.
I have also tried cmake -DCMAKE_BUILD_TYPE=Debug/Release
and it shows me the same behaviour.
In CMakeLists.txt I have also tried to set the ASAN Configs through
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -O1 -fno-omit-frame-pointer -g -fsanitize-recover=address")
but this also did not help.
I also tried to give ASAN_OPTIONS and LSAN_OPTIONS through terminal and through CLION Interface. but its not working correctly and giving the same behaviour as well.
The optimizing compiler gets rid of new
and makes the equivalent code w/o memory leaks.
#include <cstdlib>
#include <iostream>
int main(int argc, char** argv) {
std::cout << "Hello, World!\n";
int j = rand() % 9;
std::cout << "j=" << j << std::endl;
if (j < 0 || j > 9)
return 0;
std::cout << "i=" << 77 << std::endl;
return 0;
}
See the generated assembler on https://godbolt.org/z/8vsTa9GWv, the output part is just std::cout << 77
:
mov rdi, rax
mov esi, 77
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)