std::vector destructor gives error

2019-09-27 05:35发布

问题:

I have a class like this:

class Foo
{
public:
    Foo() {};

    ~Foo() {};

    void MyFunc(int a)
    {
        m_struct.my_vec.push_back(a);
    }

public:
    MyStructType m_struct;
}

and MyStructType is defined similar to this:

struct MyStructType
{
    std::vector<int> my_vec;
}

The problem is that when I instantiate the class as follows, I get a memory violation error for std::vector deallocation when the m_struct destructor is called:

void main()
{
    Foo f;
    f.m_struct.my_vec.push_back(10);
}

However, if I do it the following way, the result is the same, but I don't get any error:

int main()
{
    Foo f;
    f.MyFunc(10);
}

To me, the two methods should be identical. Given that the actual code is more complicated than the snippet above, I would prefer to make m_struct public and go with the first option. Any suggestions as why the first method gives error when vector is being deallocated?

Thanks!

UPDATE: I notices that the problem is in fact in dll_export, which I failed to mention above. I am generating a dll and using it in another project. If I drop dllexport and put the definitions of the functions (although empty) in the header file, it runs OK. But when I export my class and put the definitions in the cpp file, it is when it gives me the error. Any ideas?

回答1:

Since you said you use dll_export, the cause of corruption can be one or more of the following:

  • The application and DLL were not compiled with the same compiler options in terms of code generation.

  • The application and DLL are using different heaps at runtime.

For the first item, you must make sure that the compiler options such as structure packing, and any other option that will change the class's internals in some way, are the same. But even more basic, the app and DLL must be compiled with the same version of the compiler.

For the second item, you must make sure that the application and DLL use the same heap. To do this, both the DLL and app must use the DLL version of the runtime library.

When you have a class that handles dynamically allocated memory such as std::vector passing and using these class across module boundaries become error prone. Note that the problem is not std::vector, as any class, even one that you would have written, would have the same issue if the class uses the heap.



回答2:

Remove this line : memset(&m_struct, 0, sizeof(m_struct);

It likely corrupts the vector in MyStructType. Why are you doing that ?