双重链接结构列表 - 覆盖

时间:2016-03-01 17:44:15

标签: c++ pointers doubly-linked-list

所以我试图在C ++中创建一个在双向链表上执行基本操作的程序。我遇到的主要问题是每次我向列表添加一个新元素时,我为新元素输入的id字段将覆盖所有其他元素的id字段。 id字段是唯一执行此操作的字段,这对我来说非常困惑。我相信我的错误可能在我使用指针的某处,因为这是我在C ++中使用它们来管理列表的第一个程序(Ada中的指针对我来说似乎更简单)。我已经多次通过GDB运行我的程序,但似乎无法确定导致问题的原因。这让我相信这可能是我的逻辑错误。

这是我的主要内容:

#include <iostream>
#include "list.h"
#include <string.h>  // <string>

using namespace std;



int main (void)
{
int choice, printorder;
char idbuffer[100];
rec r; 


do
{  
   cout << "Enter your choice: 1 - Add, 2 - Delete, 3 - Print, 0 - quit. " <<endl;
   cin >> choice;

   switch ( choice )
   {
      case 1:  //AddItem
         cout << "\nEnter ID ";
         cin >> idbuffer;
         r.id = idbuffer;
         cout << "\nFirst Name ";
         cin >> r.firstname;
         cout << "\nLast Name ";
         cin >>  r.lastname;
         if ( AddItem ( r ) )
         {
            cout << "\nSuccess!\n";
         }
         else
         {
            cout << "\nItem failed to be added.\n";
         }
         break;
      case 2:  //Delete
         cout << "\nEnter id: ";
         cin >> idbuffer;
         if ( DeleteItem ( idbuffer ) ) 
         {
            cout << "\nDelete OK.\n";
         }
         else
         {
            cout << "\nDelete Failed for: " << idbuffer << endl;
         }
         break;
      case 3: // Print
        cout << "Enter order: 0 - Ascending, 1 - Descending. \n";
        cin >> printorder;
        PrintList (printorder); 
        break;
      case 0:  // quit
         break;
      default: // bad choice
         break; 
   } // end switch
} 
while ( choice != 0 );// end do while
}  // end main

这是我的文件list.h:

struct rec
{
   char * id;
   char firstname[15];
   char lastname[15];
   rec* prev;
   rec* next;
};


int AddItem ( rec r );
int DeleteItem ( char* delid );
void PrintList ( int order );

最后我的文件list.cpp中的AddItem函数:

#include <iostream>
#include "list.h"
#include <string.h>

using namespace std; 

rec * first = NULL;
rec * last = NULL;




int AddItem( rec r )
//Return: 1 if a success, 0 if failed.
//No duplicate id's, sort by lastname
{
   rec * ptr = NULL;
   rec * current;

   rec * myStruct = new rec;
   myStruct -> id = r.id;
   strcpy(myStruct -> firstname, r.firstname);
   strcpy(myStruct -> lastname, r.lastname);

   ptr = first;

   //Check for duplicate id's, currently commented out due to id's being overwritten
   //while (ptr)
   //{
   //   if (ptr -> id == myStruct -> id)
   //   {
   //       return 0;
   //   }
   //   ptr = ptr -> next;
   //}

   //ptr = first;

   if (first == NULL) //Empty
   {
      first = myStruct;  //Inserts node into empty list
      last = myStruct;
      myStruct -> prev = NULL;
      myStruct -> next = NULL;
      return 1;
   }
   else if (myStruct -> lastname > last -> lastname) //Add to end of list
   {
      last -> next = myStruct;
      myStruct -> prev = last;
      last = myStruct;
      return 1;
   }
   else if (myStruct -> lastname && myStruct -> lastname < first -> lastname) //Add to beginning of list
   {
      ptr = first;
      first = myStruct;
      myStruct -> next = ptr;
      ptr -> prev = myStruct;
      return 1;
   }
   else
   {
      current = first;
      while (current)
      {
         if (myStruct -> lastname > current -> lastname && myStruct -> lastname <= current -> next -> lastname)
         {
            ptr = current -> next;
            current -> next = myStruct;
            myStruct -> prev = current;
            myStruct -> next = ptr;
            ptr -> prev = myStruct;
            return 1;
         }
         else
         {
            current = current -> next;
         }
   }
   return 0;
}

我确信这段代码中还有其他错误和一些草率的编程,但我计划在解决这些覆盖问题之后修复这些错误并使程序更整洁/更高效,因为它也阻止了我测试我程序的其他部分。提前致谢,对于冗长的帖子感到抱歉。

Update1:​​在意识到我需要更改行

之后
myStruct -> id = r.id;

到字符串副本,例如:

strcpy(myStruct -> id, r.id);

我现在收到一个分段错误..我会想象我的指针搞砸了。回去工作我去感谢迄今为止的所有帮助!

Update2:经过更多编辑和更多错误后,我让程序正常运行!我现在正在清理和优化程序。感谢大家的好建议!

1 个答案:

答案 0 :(得分:0)

所有id对象都具有相同的值 - idbuffer的第一个字符的地址。

主要

cin >> idbuffer;
r.id = idbuffer;
       ^^^^^^^^^

然后进一步在AddItem

int AddItem( rec r )
//Return: 1 if a success, 0 if failed.
//No duplicate id's, sort by lastname
{
   rec * ptr = NULL;
   rec * current;

   rec * myStruct = new rec;
   myStruct -> id = r.id;
                    ^^^^^
   //...

您应该动态分配id将指向的内存,并且将复制具有id的实际字符串。或者您应该将数据成员id声明为字符数组。

例如在main

cin >> idbuffer;
r.id = new char[std::strlen( idbuffer ) + 1];
std::strcpy( r.id, idbuffer ); 

并在AddItem

rec * myStruct = new rec( r );

更好的方法是使用std::string类型的对象。