0

I created in an include.hpp two C++ classes:

#include <string>
#include <map>
#include <iostream>
#include <sstream>
#include<vector>
using namespace std;

class A {
        public:
                vector<char> v;
                A(){};
                A(A &other) {
                    v = other.v;
                }
                A(string s) {
                    v.assign(s.begin(), s.end());
                }

                A& operator << (std::string s) {
                    v.insert(v.end(), s.begin(), s.end());
                    return(*this);
                };
};

class B {
        protected:
                A a;
        public:
                template<typename T>
                B(T &t): a(t) {}
};

I need now to create an instance by entering to its constructor an A object. In addition the A object has to be a returned value of an other function that creates the returned A instance with the operator <<

I'm trying with the following main:

#include<iostream>
#include "include.hpp"

using namespace std;

A& createstrbyappend() {
        A a;
        a << "aa";
        return a;
}

int main() {
        A aa;
        aa << "kkk";
        cout << "create b1 object " << endl;
        B* b1 = new B(aa);
        cout << "create b2 object " << endl;
        B* b2 = new B(createstrbyappend());
        cout << "End program " << endl;
}

But I get a segmentation fault with this main, I get as output:

create b1 object 
create b2 object 
Segmentation fault (core dumped)

b1 is created successfully, but b2 that's created through the function createstrbyappend gives the segmentation fault.

Is there a suggestion how I can fix the issue ?

EDIT: add compiler version

I'm compiling with g++ command under ubuntu. my g++ version is the following:

$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Kallel Omar
  • 1,208
  • 2
  • 17
  • 51

1 Answers1

2

You are returning a function local object by reference from createstrbyappend. You should return a copy instead:

A createstrbyappend() {
 //...
}

This requires you to take the argument to Bs constructor by value as well:

template<typename T>
B(T t): a(std::move(t)) {}

Now, you need to take the argument to A's copy constructor by const&:

A(A const &other) {
   v = other.v;
}

Here's a working demo.

cigien
  • 57,834
  • 11
  • 73
  • 112