Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 链表工作不正常,头部已更新_C++_Linked List - Fatal编程技术网

C++ 链表工作不正常,头部已更新

C++ 链表工作不正常,头部已更新,c++,linked-list,C++,Linked List,我对下面的链表代码有问题,但我不确定它是什么。有人能给我指出正确的方向吗?我在一些更大的代码中使用了这段代码,在这些代码中我更新了记录,但它从未到达“创建新记录”部分。这就好像主代码正在更新head指针,因此总是产生有利的比较 提前谢谢。我一直在绞尽脑汁想弄清楚问题出在哪里 struct l_list *find_name(const char *name) { struct l_list *tmp=0; if(records==0) { // First record

我对下面的链表代码有问题,但我不确定它是什么。有人能给我指出正确的方向吗?我在一些更大的代码中使用了这段代码,在这些代码中我更新了记录,但它从未到达“创建新记录”部分。这就好像主代码正在更新head指针,因此总是产生有利的比较

提前谢谢。我一直在绞尽脑汁想弄清楚问题出在哪里

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;
}
一旦我得到结构,我会像这样更新它:

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
            }
}
struct记录{
常量字符*名称;
结构记录*下一步;
};
结构记录*头;
结构记录*尾部;
结构记录*查找名称(常量字符*名称)
{
结构记录*tmp=0;
如果(记录计数==0){//第一条记录
cout-next=0;
尾=头;
记录计数++;
回流头;
}否则{
tmp=头部;
while(tmp!=0){
如果(!std::strcmp(tmp->name,name)){

cout由于您没有告诉我们记录的结构是什么,因此任何人都无法给出正确的答案。您没有给出会导致您的函数行为不正确的代码示例,这使得它变得更加不可能

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

  • 调用代码将名称放入缓冲区,并调用
    find\u name
  • find_name
    将缓冲区的地址存储到
    records
    对象的
    name
    元素中。
    name
    因此指向缓冲区现在和将来包含的任何内容
  • 调用代码将新名称放入同一缓冲区。这自动意味着
    name
    元素现在指向该新名称,因为它指向缓冲区
  • 调用代码再次调用
    find_name
  • find_name
    将缓冲区的内容与第一个
    records
    对象的
    name
    元素指向的字符串进行比较。由于
    name
    元素包含调用者传递的缓冲区地址(从步骤2开始),这意味着它正在将缓冲区与自身进行比较。因此结果总是“平等”

  • 但是可能是
    name
    根本不是指针,在这种情况下,整个答案都是无关的。

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

        if(record_count==0) { // First record 
        cout << "Creating first record" << endl;
        //...
        } else {
        tmp=head;
        //...
    
    如果(记录计数=0){//第一条记录
    下一步;
    如果(tmp==nullptr)
    {
    cout-next=nullptr;
    if(tail==nullptr)
    {
    头=尾=tmp;
    }
    其他的
    {
    tail=tail->next=tmp;
    }
    记录++;
    }
    返回tmp;
    }
    

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

    听起来您可能需要学习如何使用调试器逐步完成代码。有了一个好的调试器,您可以逐行执行程序,并查看程序偏离的位置如果你要做任何编程,这是一个必不可少的工具。进一步阅读:使用STD::列表?或者不允许?这是C++编写的一些C代码。如果你想要C++列表,使用C++的东西作为<代码> STD:List< <代码>。如果是学校,你不允许,想想一个可以处理你的CONCE的类。Pt,使用C++现代的东西,如<代码> STD::UnjyQupTrp/代码>等。停止在代码的实例声明上使用<代码>结构>代码>这是过时的C,它只是增加了噪声。如果你想学习C++,忘记你所知道的C,学习C++,使用它的习语和设施。用C++编译器编写C是一种浪费,并且不教你什么。或者,你想使用.@ AelfLeD——我还没有看到C++初学者写一个正确的链表而没有很多经验丰富的程序员的帮助。如果这不是一个学校作业,请使用<代码> STD::列表< /C>或另一个容器类,忘记尝试这个。如果这是一个学校作业,最好的方法是知道如何使用。请看一个链表类是如何组合在一起的——获取一个快捷方式——获取C++中已经存在的代码,这样做正确,并研究它,编译它,使用调试器来遍历代码等等。然后我的答案可能是正确的。您没有在<代码>名称< /COD>中存储一个字符串,而是指向一个已被C填充的缓冲区的指针。aller并传递到函数中。使用struct格式和相关代码进行更新。您的答案听起来可能是这样的。您是说当我从main调用并传递字符串(即“Ted”)时要查找\u name并更新成员tmp->name,它会在某个点上松开指针。这似乎是正在发生的事情。那么,在这种情况下,我应该如何存储名称?我应该复制解引用实际值并将其复制到成员tmp->name中吗?实际上,我用来填充find\u name()的函数返回一个字符串(假设std::string类)。这不起作用吗?否则我怎么能第一次填写const char?谢谢,是的,我开始意识到这一点。我用来获取名称的函数返回字符串find_name(function_that_returns_name))。因此,如果我像上面那样分配一个传递的字符串文字,这是否起作用?
        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;
    }