这个bug很诡异,从头到尾不知道为什么会segmentfault。
大概代码是这样的:
nclude "cv_bridge/cv_bridge.h"
#include "glog/logging.h"
using namespace std;
using namespace google;
using namespace cv;
SSDDetector* detector;
void cbImg() {
// will can detector
detector->detect();
}
int main() {
detector = new SSDDetector();
}
也就是说,我把所有的代码写道了一个文件里面,没有用头文件,其中有一个detector指针需要定义为全局变量,这样可以在我的方法中调用。然后我在主函数里面初始化了这个指针。
代码能够编译,但是运行的时候segmentfault。
用gdb debug的时候显示,恰恰就是detector这个内存引起了一段错误。那么问题来了,这种方式哪里不对吗?
更新:
#include <string>
#include <pluginlib/class_list_macros.h>
#include <string>
#include <image_transport/image_transport.h>
#include <object_msgs/ObjectsInBoxes.h>
#include "detector/mb_ssd_voc.h"
#include "cv_bridge/cv_bridge.h"
#include "glog/logging.h"
using namespace std;
using namespace google;
using namespace cv;
ros::Publisher pub;
SSDDetector* detector = nullptr;
void cbImage(const sensor_msgs::ImagePtr image_msg)
{
cv_bridge::CvImagePtr cv_ptr;
cv_ptr = cv_bridge::toCvCopy(image_msg);
cv::Mat img = cv_ptr->image;
std::vector<vector<float>> detections = detector->Detect(img);
object_msgs::ObjectsInBoxes objects;
for (int j = 0; j < detections.size(); ++j) {
const vector<float> &d = detections[j];
object_msgs::ObjectInBox object_in_box;
object_in_box.object.object_name = detector->CLASSES[d[1]];
object_in_box.object.probability = d[2];
object_in_box.roi.x_offset = img.cols * d[3];
object_in_box.roi.y_offset = img.rows * d[4];
object_in_box.roi.height = img.cols*(d[5]-d[3]);
object_in_box.roi.width = img.rows*(d[6]-d[4]);
objects.objects_vector.push_back(object_in_box);
}
pub.publish(objects);
}
int main(int argc, char **argv) {
string _model_file = "/media/jintain/wd/ros/workspaces/cs_rs/src/ros_gpu_caffe/models/ssdlite/mb2_ssdlite_voc_new.prototxt";
string _weights_file = "/media/jintain/wd/ros/workspaces/cs_rs/src/ros_gpu_caffe/models/ssdlite/mb2_ssdlite_voc_new.caffemodel";
string _mean_file;
string _mean_value = "0.5,0.5,0.5";
float _confidence_threshold = 0.7;
float _normalize_value = 0.007843;
string _cpu_mode = "gpu";
int _resize_mode = 0;
ros::init(argc, argv, "talker");
ros::NodeHandle nh("~");
if (!nh.getParam("net_config_path", _model_file))
{
ROS_WARN("param net_cfg_path not set, use default");
} else {
LOG(INFO) << "net_config_path: " << _model_file << endl;
}
if (!nh.getParam("weights_path", _weights_file))
{
ROS_WARN("param weights_path not set, use default");
} else {
LOG(INFO) << "weights_path: " << _weights_file << endl;
}
detector = new SSDDetector(_model_file, _weights_file, _mean_file, _mean_value,
_confidence_threshold, _normalize_value, _cpu_mode,
_resize_mode);
LOG(INFO) << "detector initialized!!\n";
ros::Subscriber sub = nh.subscribe("/usb_cam/image_raw", 1000, cbImage);
pub = nh.advertise<object_msgs::ObjectsInBoxes>("detection", 100);
}
这个detector是我封装的类,里面的实现其实不用管,因为其他的程序运行没有任何问题,但是就是i这种写法除了问题。。。
为什么在文件开头初始化一个这样的东西,就crash呢? 我吧nullptr去掉也是一样