【问题标题】:C++ Union fields not set correclyC++ 联合字段未正确设置
【发布时间】:2013-08-15 07:33:32
【问题描述】:

我有一个模板联合类型 NodeType。 问题是,在分配其变量字段时未正确设置,并且在随后访问时包含垃圾值。具体来说,问题出现在 _field1 和 _field2 - 请参阅主目录。

#include <cstdlib>
#include <iostream>

using namespace std;


        template <class T>
        struct structExampleType                
        {
          T _structField;
          typedef structExampleType<T>* pointerStructExample;
        };


         enum TYPE_tag
         {FIELD1_tag, FIELD2_tag} TYPE_tag; 

          template <class T>//, class P>
          union NodeType
          {
           enum TYPE_tag _nodeType_tag;
           char _field1;
           typename structExampleType<T>::pointerStructExample _field2;

           NodeType(){_field2=0;}

           NodeType(enum TYPE_tag nodeType_tag, char _charField)
           {
            _nodeType_tag=nodeType_tag;
            _field1=_charField;
            //_field2=0;
           }  

           NodeType(enum TYPE_tag nodeType_tag, typename structExampleType<T>::pointerStructExample pointer)
           {
            _nodeType_tag=nodeType_tag;
            _field2=pointer;
            //_field1='-';
           }          

          };







int main(int argc, char *argv[])
{
    NodeType<int> node1, node2;
    structExampleType<int>* structExamplePointer;

    structExamplePointer=new structExampleType<int>();

    structExamplePointer->_structField=100;
//    structExamplePointer->_field2=structExamplePointer;

    node1=NodeType<int>(FIELD1_tag,'-');
    node2=NodeType<int>(FIELD2_tag,structExamplePointer);    


    cout<<endl<<"node1: ";    
    if (node1._nodeType_tag==FIELD1_tag)
    {cout<<node1._field1<<endl;}
    else
    {cout<<node1._field2<<endl;}        


    cout<<endl<<"node2: ";
    if (node2._nodeType_tag==FIELD2_tag)
    {cout<<node2._field1<<endl;}
    else
    {
        cout<<node2._field2<<endl;
        cout<<(node2._field2)->_structField<<endl;
    }  



    system("PAUSE");
    return EXIT_SUCCESS;
}

可能是什么问题?提前感谢您的宝贵时间。

【问题讨论】:

  • 您正在使用未初始化的指针。我根本不明白为什么需要指针。

标签: c++ unions unassigned-variable


【解决方案1】:

main 中有这两行:

structExampleType<int>* structExamplePointer;

structExamplePointer->_structField=100;

请记住,除非它们具有默认构造函数(指针没有),否则不会初始化局部变量,因此第二次取消引用未初始化的指针 structExamplePointer,会导致未定义的行为。

当您尝试设置多个字段时,您似乎也误解了union 的用途。在union 中,所有字段共享 相同的空间,因此当写入一个成员时,所有成员都会更改。只有最后一次写给成员是有效的。尝试使用其他字段可能会再次导致未定义的行为。


如果你需要有一个“标签”字段其他数据,包含标签和联合数据的结构应该是你的选择:

struct NodeType
{
    enum TAG_Type
    {
        FIELD1,
        FIELD2
    } type;

    union
    {
        char field1;
        struct some_struct* field2;
    }
};

【讨论】:

  • 我会改变“局部变量根本没有初始化”的措辞。 std::string s; //empty string
  • @chris 现在怎么样?
  • 是的,这样更好。从技术上讲,您仍然可以执行int i{1}; 之类的操作,但是为了 OP 的代码,它可以理解这一点。一般的初始化规则是不相关的。
  • ok 修复了其他任务。从其他答案来看,关键是我应该为每个联合变量只做一个分配。
  • @geraldCelente,并且只使用最后设置的那个。
【解决方案2】:

对于union,成员试图占用内存中的相同空间,因此您的构造函数通过分配给每个成员并相互覆盖而导致问题。

联合只有容纳其最大数据成员所需的大小。其他数据成员分配在与该最大成员的一部分相同的字节中。

【讨论】:

  • 好的,我到了。但是问题是我需要一种机制来保存存储在联合中的变量类型,并且这些信息应该保存在联合本身中。知道如何实现这一目标吗?
【解决方案3】:

您实际上在这里拥有的不是 field1 和 field2 的并集,而是 { tag, field1, field2 } 的并集。这就是你看到垃圾的原因。 Union 仍然是一个单一的内存区域,但你在构造逻辑中将它设置了三倍。

您可以从更简单的案例开始并阅读一些文档,例如,http://msdn.microsoft.com/en-us/library/5dxy4b7b.aspx

为了实现你的目标,你可能会做这样的事情(你需要你的标签在联合之外):

联合 MyUnionType { 整数数据整数; 双数据_双; }

typedef enum { IntTag, DoubleTag } UnionTypeTag;

类 MyVariableClass { 私人的: MyUnionType m_variableField; UnionTypeTag m_variableFieldType; }

另一种方法是设计您的代码,以便在代码路径中的任何位置您都知道您正在处理的联合类型的“风格”。

我个人的看法是,后者(总是知道你的工会“风味”是什么)是 K&R 在想到工会概念时的想法。

【讨论】:

  • 好的,我到了。但是问题是我需要一种机制来保存存储在联合中的变量类型,并且这些信息应该保存在联合本身中。知道如何实现这一目标吗?
  • 我不是在这里质疑你的设计(也许联合不是解决你问题的正确方法)。所以,如果我们把设计放在一边,你的“标签”应该在联合本身之外。我正在用一个例子更新我的答案。
【解决方案4】:

您能否在使用之前初始化您的指针structExampleType&lt;int&gt;* structExamplePointer

由于取消引用未初始化的指针是导致问题的原因

【讨论】:

  • 好的。从其他答案来看,关键是我应该为每个联合变量只做一个分配。
猜你喜欢
  • 1970-01-01
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多