0

Code below causes segmentation fault on g++ 5.4.0 20160609. But it works on vs c++ 11.0.

#include <string>
#include <iostream>
#include <vector>

struct fooStruct{
    std::string str;
    fooStruct() : str(std::string("")){}
};

int main()
{
    fooStruct fooObj;

    std::vector<char> cont(sizeof(fooStruct));
    std::cout<<"Size of string = "<<sizeof(std::string)<<std::endl;
    std::cout<<"Size of vec = "<<cont.size()<<std::endl;

    std::cout<<sizeof(fooObj)<<std::endl;

    char* ptr = cont.data();
    ((fooStruct*)(ptr))[0] = fooObj;            //segmentation fault
    //((fooStruct*)(ptr))[0].str = fooObj.str; //segmentation fault

    std::cout<<((fooStruct*)(ptr))[0].str<<std::endl;

    return 0;

}

The only difference between compilers is that msvc takes 40 bytes for string, while gcc only 32. But i don't think that it does matter here. Why does it work on msvc and does not work on g++?

Sklert
  • 242
  • 5
  • 12

1 Answers1

2

Your code has undefined behavior. That means it could "work" or it could blow up, both are valid outcomes.

ptr points to a char array. It does not represent a fooStruct. So when you do

((fooStruct*)(ptr))[0]

You treat that memory as if it was a fooStruct even though it is not which is undefined behavior.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • @juanchopanza Is it? They did use `sizeof(fooStruct)` for the number of `char`'s. – NathanOliver Mar 22 '18 at 15:46
  • Yeah, you're right. What's also wrong is the string copy. – juanchopanza Mar 22 '18 at 15:47
  • Yeah. I figured that was covered by my answer though since if `((fooStruct*)(ptr))[0]` is UB then `((fooStruct*)(ptr))[0].anything` is also UB. – NathanOliver Mar 22 '18 at 15:48
  • It should be noted that even though the memory does not point to a `fooStruct`, it can be made to, by constructing a `fooStruct` object in that location first, via placement new. And then the dereference, as well as the assignment would be perfectly well defined behavior. – Benjamin Lindley Mar 22 '18 at 16:04
  • @BenjaminLindley I was thinking that but couldn't that still be an issue as the char array doesn't have to be aligned to the structs alignment? – NathanOliver Mar 22 '18 at 16:06
  • Thank you. But I guess it should work correctly if struct is POD. Correct me, if it is not true. The reason why it works on msvc is mb in different implementation of `std::string` not in UB. – Sklert Mar 22 '18 at 16:07
  • 1
    @Sklert If the struct is a POD type then it is okay as long as the underlying array is properly aligned. I'm not sure if it would be or not but I'm leaning towards it could not be. – NathanOliver Mar 22 '18 at 16:10