代码之家  ›  专栏  ›  技术社区  ›  dragonmantank

将一个指针指定给另一个指针时出现SEGFULT

  •  0
  • dragonmantank  · 技术社区  · 16 年前

    我们需要做的是生成对象的链接列表(a Employee 对象),然后将该信息显示回用户。每当我尝试将对象分配到链表容器中时,它都会出错。

    我有以下链接列表对象:

    class LinkedListContainer {
        private:
            Employee *emp;
            LinkedListContainer *next;
    
        public:
            Employee getEmployee() { return *emp; }
    
            void setEmployee(Employee *newEmp) {
                *emp = *newEmp // This is what is causing the segfault
            }
    
            LinkedListContainer getNext() { return *next; }
    
            void setNext(LinkedListContainer *newContainer) {
                *next = *newContainer;
            }
    }
    

    7 回复  |  直到 16 年前
        1
  •  5
  •   CB Bailey    16 年前

    看看你的类,似乎没有一个地方可以放置指针 emp 设置为指向实际对象。

    *emp = *newEmp;
    

    指定所指向的对象的值 newEmp 指向所指向的对象 电磁脉冲 . 除非两个指针都指向有效对象,否则代码将具有未定义的行为。

    你最好吃点东西 电磁脉冲 作为Employee对象而不是指向需要手动管理指向对象的生命周期的对象的指针。

    这假设您的 LinkedListContainer 类是将拥有 Employee .

    另一方面,当您这样做时:

    *next = *newContainer;
    

    根据命名,我假设您只想将下一个指针指向另一个指针 LinkedListContainer 对此,您可能希望执行以下操作:

    next = newContainer;
    

    因为这会将指针的值指定给变量 next

    在设计类和使用指针时,需要明确哪些对象拥有哪些其他对象,并确保适当地管理它们的生命周期。

        2
  •  2
  •   jestro    16 年前
    *emp = *newEmp;
    

    应该是:

    emp = newEmp;
    

    因此,您指定的是指针,而不是指针指向的对象。

        3
  •  1
  •   Drew Hall    16 年前

    你的 emp 指针未初始化,所以当您尝试取消引用它时( *emp )在 setEmployee()

    您最好按值保留Employee(假设它不是多态的),并按常量引用向setEmployee传递Employee对象:

    class LinkedListContainer {
      Employee emp;
    
      // ...
    
      void setEmployee(const Employee& newEmp) {
        emp = newEmp;
      }
    
      // ...
    };
    

    当然,您还需要调整其他成员函数,以反映使用值与指针的区别。

        4
  •  0
  •   Anon.    16 年前
    *emp = *newEmp
    

    您不想这样做-事实上,您根本不想取消对任何指针的引用。

    emp = newEmp
    
        5
  •  0
  •   BjoernD    16 年前

    默认情况下,emp是一个不指向任何地方的指针。通过写作

    *emp = *newEmp;
    

    如果您的容器要包含完整的Employee,那么最好将emp声明为Employee类型(而不是像现在这样指向Employee的指针)。然后

    emp = *newEmp;
    

    虽然我不确定这是否就是你需要解决的关于LinkedListContainer的所有问题,但它会起作用。

        6
  •  0
  •   MadcapLaugher    16 年前

    您遇到的问题之一是访问指针时的前导*。当访问指针时,*告诉编译器的是,指针指向的地址应该读取指针指向的位置的值,而不是读取指针指向的地址。

    一个例子是,变量就像保存值的房子。指针就像房子上的地址。通常,当编译器读取指针时,它只看到地址。当您将*放在指针前面时,它会告诉编译器查看“房子”内部以提取其中的值。当您为指针分配新地址时,您不想使用*或复制值而不是地址。

    next = newContainer;
    
        7
  •  0
  •   Dominic.wig    16 年前

    前面的答案解释了分段错误的原因。无论如何,如果您需要该示例用于学术用途,那么您可能忘记了初始化类成员。第二个问题是内存管理——谁分配/释放这些对象?在您的示例中没有构造函数,也没有析构函数:)

    您的类可以如下所示:

    class LinkedListContainer 
    {    
        public:        
            LinkedListContainer()
                : d_emp( 0 ) 
                , d_next( 0 )
            {
            }
    
            bool isValid() const
            {
                const bool result = ( d_emp != 0 );
                return result;
            }
    
            const Employee& getEmployee() const
            { 
                assert( isValid() );
                return *d_emp; 
            }        
    
            void setEmployee( Employee* emp ) 
            {            
                d_emp = emp;
            }        
    
            LinkedListContainer* getNext() 
            { 
                return d_next; 
            }        
    
            void setNext( LinkedListContainer* next )
            {            
                d_next = next;        
            }
    
        private:        
            Employee* d_emp;        
            LinkedListContainer* d_next;    
    
    };
    

    typedef boost::shared_ptr< Employee > SmartEmployee;
    
    class LinkedListContainer 
    {    
        public:        
            LinkedListContainer()
                : d_next( 0 )
            {
            }
    
            bool isValid() const
            {
                return d_emp;
            }
    
            const Employee& getEmployee() const
            { 
                assert( isValid() );
                return *d_emp; 
            }        
    
            void setEmployee( SmartEmployee emp ) 
            {            
                d_emp = emp;
            }        
    
            LinkedListContainer* getNext() 
            { 
                return d_next; 
            }        
    
            void setNext( LinkedListContainer* next )
            {            
                d_next = next;        
            }
    
        private:        
            SmartEmployee d_emp;        
            LinkedListContainer* d_next;    
    
    };