链接列表无法正常工作,而是更新了头

时间:2016-06-10 13:25:18

标签: c++ linked-list

我对以下链接列表代码有疑问,但我不确定它是什么。有人能指出我正确的方向吗?我在一些更大的代码中使用此代码来更新记录,但它从未到达"创建新记录"部分。就好像主代码更新头指针而不是总是导致有利的比较。

提前致谢。我试图弄清问题是什么,我一直在绞尽脑汁。

struct l_list *find_name(const char *name)
{
    struct l_list *tmp=0;
    if(records==0) { // First record
        head=new l_list;
        head->name=name;
        head->next=0;
        tail=head;
        records++;
        return head;
    } 
    else {
        tmp=head;
        while(tmp!=0)
        {
        if(!std::strcmp(tmp->name,name)) 
        {
            cout << "Returning existing record with value: " << tmp->number << " name:" <<      tmp->name << endl;
            return tmp;
        }
        tmp=tmp->next;
    }
    // No first and no existing records
    cout << "Creating new record" << endl;
    tail->next=new l_list;
    tail=tail->next;
    tail->name=name;
    tail->next=0;
    records++;
    return tail;
}

我从主要用以下方式调用此方法:     struct records * tmp = find_name(&#34; Max&#34;);

然后:

tmp=find_name("Eva");

一旦我得到结构,我就像这样更新它:

tmp->number=1;

甚至更新名称:

tmp->name="Peter";

因此,通过将字符串传递给函数,它将创建一个新记录并返回它或给出一个现有记录并返回该记录。输出中的问题可能不明显,但是当你把它放在main中的for(;;)循环时它会 搞砸了。

结构如下:

struct records {
      const char *name;
      struct records *next;
}   

相关的程序代码是:

struct record {
        const char *name;
        struct record *next;
};
struct record *head;
struct record *tail;

struct record *find_name(const char *name)
{
        struct record *tmp=0;

        if(record_count==0) { // First record 
        cout << "Creating first record" << endl;
        head=new record;
        head->name=name;
        head->next=0;
        tail=head;
        record_count++;
        return head;
        } else {
        tmp=head;
        while(tmp!=0) {
        if(!std::strcmp(tmp->name,name)) {
        cout << "Returning existing record with value: " << "name: " << name << "tmp->name: " << tmp->name << endl;
        return tmp;}
        tmp=tmp->next;
        }

        // No first and no existing records
        cout << "Creating new record" << endl;

        tail->next=new record;
        tail=tail->next;
        tail->name=name;
        tail->next=0;
        record_count++;
        return tail;
        }

}

int main(int argc, const char *argv[]) 
{
struct record *tmp=0;

            if(something is true) {
            //Return or create a new user
            tmp=find_name("Peter");

            } else {
            tmp=find_name("Unknown"); // Hold 1 unknown person in database
            }
}

我知道它不是可编辑的,但我必须从更大的部分中提取它。

2 个答案:

答案 0 :(得分:0)

由于您尚未告诉我们records结构是什么,因此任何人都无法给出正确答案。通过不提供会导致函数行为不正确的代码示例,您已经变得更加不可能了。

如果name元素是char *指针,那么您可以轻松获得此行为。例如:

  1. 调用代码将名称放入缓冲区,并调用find_name
  2. find_name 将缓冲区的地址存储到name对象的records元素中。因此,name指向缓冲区现在和将来包含的内容。
  3. 调用代码将新名称放入同一缓冲区。这自动意味着name元素现在指向该新名称,因为它指向缓冲区。
  4. 调用代码再次调用find_name
  5. find_name将缓冲区的内容与第一个name对象的records元素指向的字符串进行比较。由于name元素包含调用者传递的缓冲区的地址(从步骤2开始),这意味着它将缓冲区与自身进行比较。所以结果始终是&#34;等于&#34;。
  6. 但可能name根本不是指针,在这种情况下,整个答案都无关紧要。

答案 1 :(得分:0)

首先不要使用以下代码格式

    if(record_count==0) { // First record 
    cout << "Creating first record" << endl;
    //...
    } else {
    tmp=head;
    //...

很难阅读这样的代码。这只是一种糟糕的编程风格。

该功能本身可以采用以下方式

struct l_list * find_name( const char *name )
{
    struct l_list *tmp = head;

    wjile ( tmp != nullptr && std::strcmp( tmp->name, name ) != 0 ) tmp = tmp->next;

    if ( tmp == nullptr )
    {
        cout << "Creating new record" << endl;
        tmp = new l_list;
        tmp->name = name;            
        tmp->next = nullptr;

        if ( tail == nullptr )
        {
            head = tail = tmp;
        }
        else
        {
            tail = tail->next = tmp;
        }

        records++;
    }

    return tmp;
}

考虑到节点可以包含指向字符串的指针,这些指针具有静态存储持续时间,例如字符串文字或在堆中分配。