Mixing C++ Containers with C language structs

1

I have spent 2 days chasing an issue involving C++ container, std::list, and C-Style structs. Is the following undefined behavior (Note the type for the std::list parameter)?

#include <list>
#include <iostream>

using std::cout;
using std::endl;

struct Point_Struct
{
  int x;
  int y;
};

typedef struct Point_Struct Point;

int main()
{
  std::list<Point> line;
  Point p;
  p.x = 3;
  p.y = 10;
  line.push_back(p);

  cout << "Size of container: " << line.size() << "\n";

  //  Here's the issue:
  line.pop_back();

  //  The size should be zero.
  cout << "Size of container after pop_back(): " << line.size() << "\n";

  return 0;
}

I ran this on Visual Studio 2017 and I get an exception error, 0xC0000005, (memory access) on the call to pop_back.

The exception is also thrown on any method that changes the ordering of the items in the list, such as assignment and sort.

If I change the type of line to std::list<Point_Struct>, there are no exceptions thrown.

Note: The issue was found in a larger program. The code above illustrates the root cause of the issue: std::list<typedef struct> vs. std::list<struct>

Note: The exception is thrown in VS2017 debug mode but not in release mode.

Sorry, but multiple questions follow:

  1. Is there anything in standard C++ (11 or later) declaring undefined behavior for using a typedef instead of a struct as the template parameter for std::list?

  2. Would this be a Visual Studio bug?

I haven't tried on G++ or other compilers.

Edit 1: VS2017 version info
Microsoft Visual Studio Professional 2017
Version 15.9.14
Installed product: Visual C++ 2017 - 00369-60000-00001-AA071

Compilation Info
Configuration: Debug
Platform: Win32
Warning Level: Level3 (/W3)
Optimization: Disabled (/Od)
Enable C++ Exception: Yes (/EHsc)
Basic Runtime Checks: Both (/RTC1)
Disable Language Extensions: No
Conformance mode: No

Platform
Platform: Windows 7

c++
asked on Stack Overflow Aug 13, 2019 by Thomas Matthews • edited Aug 13, 2019 by Thomas Matthews

1 Answer

-1

I compiled and ran your code with g++ 11 in Eclipse (Ubuntu 18) and it worked perfectly,

Output:

Size of container: 1
Size of container after pop_back(): 0

Have you tried/is it possible to swap typedef for using? This might fix it:

#include <list>
#include <iostream>

using std::cout;
using std::endl;

struct Point_Struct
{
  int x;
  int y;
};

using Point = Point_Struct;

int main()
{
  std::list<Point> line;
  Point p;
  p.x = 3;
  p.y = 10;
  line.push_back(p);

  cout << "Size of container: " << line.size() << "\n";

  //  Here's the issue:
  line.pop_back();

  //  The size should be zero.
  cout << "Size of container after pop_back(): " << line.size() << "\n";

  return 0;
}
answered on Stack Overflow Aug 13, 2019 by Alexandre Senges

User contributions licensed under CC BY-SA 3.0