当将g ++编译器标志更改为-std = c ++ 11时,使用armadillo +进行分段错误

时间:2018-05-17 07:58:24

标签: c++ c++11 cmake armadillo

项目布局

├── CMakeLists.txt
├── README.md
├── cppml.pc.in
├── examples
│   ├── AccuracyScoreEx.cpp
│   └── CMakeLists.txt
├── include
│   └── cppml
│       ├── Prerequisites.h
│       └── metrics
│           └── AccuracyScore.h
└── src
    ├── CMakeLists.txt
    └── metrics
        └── AccuracyScore.cpp

CMakeLists.txt的内容

cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
project(cppml VERSION 1.0.1 LANGUAGES CXX)
include(GNUInstallDirs)

find_package(Armadillo REQUIRED)

configure_file(cppml.pc.in cppml.pc @ONLY)

add_subdirectory(src)
add_subdirectory(examples)
#add_subdirectory(tests)

内容src/CMakeLists.txt

# set source files
set (sources
  metrics/AccuracyScore.cpp
)

# define library targets
add_library(cppml SHARED
  ${sources}
)

# target properties
set_target_properties(cppml PROPERTIES
 VERSION ${PROJECT_VERSION}
 SOVERSION 1
 CXX_VISIBILITY_PRESET hidden
)

# define headers for this lib. PUBLIC headers are used for compiling
# the library, and will be added to user's build path.
target_include_directories(cppml PUBLIC
  $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
  $<INSTALL_INTERFACE:include>
  PRIVATE ${PROJECT_SOURCE_DIR}/src
)

# Link with externel libs
target_link_libraries(cppml ${ARMADILLO_LIBRARIES})

# target_compile_features(cppml
#   PUBLIC
#     cxx_std_11 #XXX: PROBLEM HERE!
# )

# Install
install(TARGETS cppml
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ 
  DESTINATION     ${CMAKE_INSTALL_INCLUDEDIR}
)

install(FILES ${CMAKE_BINARY_DIR}/cppml.pc
  DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig
)

问题是,当我使用上面的设置构建项目时,这会产生正确的结果:

g++  -o AccuracyScoreEx AccuracyScoreEx.cpp -lcppml

但不是这样:

g++ -std=c++11 -o AccuracyScoreEx AccuracyScoreEx.cpp -lcppml
./AccuracyScoreEx
Segmentation fault: 11

以下是源代码:

Prerequisites.h

#ifndef INCLUDE_CPPML_PREREQUISITES_H_
#define INCLUDE_CPPML_PREREQUISITES_H_

//  armadillo
#include <armadillo>

#endif  // INCLUDE_CPPML_PREREQUISITES_H_

AccuracyScore.h

#ifndef INCLUDE_CPPML_METRICS_ACCURACYSCORE_H_
#define INCLUDE_CPPML_METRICS_ACCURACYSCORE_H_

#include "cppml/Prerequisites.h"

namespace cppml {
namespace metrics {

extern "C" double accuracy_score(const arma::ivec &y_true,
                    const arma::ivec &y_pred,
                    const bool normalize = true,
                    const arma::vec &sample_weight = arma::vec());

}  // namespace metrics
}  // namespace cppml

#endif  // INCLUDE_CPPML_METRICS_ACCURACYSCORE_H_

AccuracyScore.cpp

#include "cppml/metrics/AccuracyScore.h"

#define EXPORT __attribute__((visibility("default")))

namespace cppml {
namespace metrics {

EXPORT
double accuracy_score(const arma::ivec &y_true,
                  const arma::ivec &y_pred,
                  const bool normalize,
                  const arma::vec &sample_weight) {

  arma::uvec score = (y_true == y_pred);
  arma::vec dscore = arma::conv_to<arma::vec>::from(score);

  if (normalize) {
    return (sample_weight.n_elem > 0) ? 
            arma::mean(dscore % sample_weight) : 
            arma::mean(dscore);
  } else if (sample_weight.n_elem > 0) {
    return arma::dot(dscore, sample_weight);
  } else {
    return arma::sum(dscore);
  }
}

}  // namespace metrics
}  // namespace cppml

在使用gdb进行黑客攻击之后,事实证明此人y_true == y_pred(按元素比较,生成01)会导致{{ 1}}问题。但为什么只有'-std = c ++ 11'开启时才会发生?

修改:添加了示例程序 segmentation fault

AccuracyScoreEx.cpp

非常感谢任何帮助!

0 个答案:

没有答案