从使用 make 编译的程序中使用库时应用程序崩溃
Application crash when using library from the program compiled with make
我正在用 C++ 在命令行中制作科学计算器以供我使用和练习。我在 windows 上使用带有 mingw 的 cmake 编译它时遇到问题。这些是我的源文件:
main.ccp
#include <iostream>
#include <string>
#include "ExpressionCalculations/ExpressionParser.h"
int main()
{
std::string humanReadableExpression;
std::cout<<"Enter expression\n";
std::getline(std::cin, humanReadableExpression);
std::cout<<humanReadableExpression;
ExpressionCalculations::ExpressionParser parser;
auto&& expression = parser.GenerateRpnExpression(humanReadableExpression);
return 0;
}
ExpressionParser.h
#pragma once
#include <memory>
#include <stack>
#include <string>
#include <unordered_map>
namespace ExpressionCalculations
{
class ExpressionParser
{
public:
std::unique_ptr<std::string> GenerateRpnExpression(std::string &humanReadableExpression);
private:
// other code
};
}
ExpressionParser.cpp
#include <memory>
#include <stack>
#include <string>
#include <unordered_map>
#include <iostream>
#include "ExpressionParser.h"
namespace ExpressionCalculations
{
std::unique_ptr<std::string> ExpressionParser::GenerateRpnExpression(
std::string& humanReadableExpression)
{
std::unique_ptr<std::string> rpnExpression;
*rpnExpression="3456";
return rpnExpression;
}
这些是 cmake 文件
主要CMakeLists.txt
cmake_minimum_required (VERSION 2.8)
project (ScientificCalculator_exe)
add_subdirectory(ExpressionCalculations)
add_executable(ScientificCalculator main.cpp)
target_link_libraries(ScientificCalculator ExpressionCalculations)
模块CMakeList.txt
set(calculators ExpressionParser.h ExpressionParser.cpp)
add_library(ExpressionCalculations ${calculators})
当我 运行 它时,我可以看到 Enter expression 并传递输入。然后我得到分段错误。但是,当我删除 ExpressionParser 和 auto&& 表达式的声明时,会显示字符串,可以输入字符串并在命令中显示。我检查了配置问题 multiple directories under cmake, https://cmake.org/cmake-tutorial/ and https://www.codeproject.com/Articles/1181455/A-CMake-tutorial-for-Visual-Cplusplus-developers,但似乎我正确地制作了 cmake 文件。我不知道为什么它不起作用。我在 windows 上使用最新的 mingw64 和默认的 make 编译参数。
来自 unique_ptr 上的 cppreference page:
The class satisfies the requirements of MoveConstructible and MoveAssignable, but not the requirements of either CopyConstructible or CopyAssignable.
在您的 ExpressionParser::GenerateRpnExpression
函数中,您试图在应该移动它时将 unique_ptr 复制到函数之外。尝试 return std::move(rpnExpression)
在调试了只用g++编译的程序后,我发现了问题。这是对 unique_ptr' 默认构造函数行为的误解。我以为它会初始化 std::string 但在阅读文档并检查它后它不会初始化对象并生成 nullptr。然后我查看了 Scott Myers 的 Modern Effective C++ 如何初始化 unique_ptr。我使用 auto rpnExpression = std::make_unique<std::string>();
而不是 std::unique_ptr<std::string> rpnExpression;
。它就像魅力一样。我通过cmake检查编译没有任何问题。
我正在用 C++ 在命令行中制作科学计算器以供我使用和练习。我在 windows 上使用带有 mingw 的 cmake 编译它时遇到问题。这些是我的源文件:
main.ccp
#include <iostream>
#include <string>
#include "ExpressionCalculations/ExpressionParser.h"
int main()
{
std::string humanReadableExpression;
std::cout<<"Enter expression\n";
std::getline(std::cin, humanReadableExpression);
std::cout<<humanReadableExpression;
ExpressionCalculations::ExpressionParser parser;
auto&& expression = parser.GenerateRpnExpression(humanReadableExpression);
return 0;
}
ExpressionParser.h
#pragma once
#include <memory>
#include <stack>
#include <string>
#include <unordered_map>
namespace ExpressionCalculations
{
class ExpressionParser
{
public:
std::unique_ptr<std::string> GenerateRpnExpression(std::string &humanReadableExpression);
private:
// other code
};
}
ExpressionParser.cpp
#include <memory>
#include <stack>
#include <string>
#include <unordered_map>
#include <iostream>
#include "ExpressionParser.h"
namespace ExpressionCalculations
{
std::unique_ptr<std::string> ExpressionParser::GenerateRpnExpression(
std::string& humanReadableExpression)
{
std::unique_ptr<std::string> rpnExpression;
*rpnExpression="3456";
return rpnExpression;
}
这些是 cmake 文件
主要CMakeLists.txt
cmake_minimum_required (VERSION 2.8)
project (ScientificCalculator_exe)
add_subdirectory(ExpressionCalculations)
add_executable(ScientificCalculator main.cpp)
target_link_libraries(ScientificCalculator ExpressionCalculations)
模块CMakeList.txt
set(calculators ExpressionParser.h ExpressionParser.cpp)
add_library(ExpressionCalculations ${calculators})
当我 运行 它时,我可以看到 Enter expression 并传递输入。然后我得到分段错误。但是,当我删除 ExpressionParser 和 auto&& 表达式的声明时,会显示字符串,可以输入字符串并在命令中显示。我检查了配置问题 multiple directories under cmake, https://cmake.org/cmake-tutorial/ and https://www.codeproject.com/Articles/1181455/A-CMake-tutorial-for-Visual-Cplusplus-developers,但似乎我正确地制作了 cmake 文件。我不知道为什么它不起作用。我在 windows 上使用最新的 mingw64 和默认的 make 编译参数。
来自 unique_ptr 上的 cppreference page:
The class satisfies the requirements of MoveConstructible and MoveAssignable, but not the requirements of either CopyConstructible or CopyAssignable.
在您的 ExpressionParser::GenerateRpnExpression
函数中,您试图在应该移动它时将 unique_ptr 复制到函数之外。尝试 return std::move(rpnExpression)
在调试了只用g++编译的程序后,我发现了问题。这是对 unique_ptr' 默认构造函数行为的误解。我以为它会初始化 std::string 但在阅读文档并检查它后它不会初始化对象并生成 nullptr。然后我查看了 Scott Myers 的 Modern Effective C++ 如何初始化 unique_ptr。我使用 auto rpnExpression = std::make_unique<std::string>();
而不是 std::unique_ptr<std::string> rpnExpression;
。它就像魅力一样。我通过cmake检查编译没有任何问题。