通过指针时出现分段错误

矿物质

问题:原来的问题是添加2个数字存储为链表(每个数字存储在一个节点中)。试图打印链表的节点。但是在传递给“Print()”时抛出分段错误。但是 Print() 工作了前 2 次(我只是在这里走运了吗?)。(注意:代码很乱,因为我正在尝试不同的东西来学习 C++。而且我对 valgrind 没有任何经验,所以我可能不会在命令中使用正确的选项)。

尝试 cout 语句来定位抛出 SIGSEGV 的位置。
尝试使用 Valgrind 获取更多信息。注意到更多错误。
即: 1.
有条件的跳转或移动取决于未初始化的值
2. 使用未初始化的大小值 3. 大小
读取无效

代码:

#include <iostream>

using namespace std;

struct Node{
    int digit;
    Node *next;
    Node(int d): digit(d) { next = NULL;}
    Node(){}
};

struct Node* head1;
struct Node* head2;
struct Node* s;

void insert(struct Node* &head, struct Node &node){
    struct Node* temp; 
    temp = new Node(node.digit);
    //(*temp).digit = node.digit;
    if(head != NULL){
        temp->next = head;
    }
    head = temp;
}

void print(struct Node* head){
    cout<<"Print: "<<endl;
    while(head!=NULL){
        cout<<head->digit;
        head = head->next;
    }
    cout<<endl;
}

struct Node* add(struct Node* head1, struct Node* head2){
    struct Node* sum;
    int carry = 0;
    while(head1!=NULL && head2!=NULL){
        int x = head1->digit + head2 ->digit + carry;
        carry = x/10;
        x = x%10;
        struct Node t(x);
        insert(sum,t);
        head1 = head1 -> next;
        head2 = head2 -> next;
    }
    while(head1!=NULL){
        struct Node t((head1->digit)+carry);
        carry=0;
        insert(sum,t);
        head1 = head1 -> next;
    }
    while(head2!=NULL){
        struct Node t((head2->digit)+carry);
        carry=0;
        insert(sum,t);
        head2 = head2 -> next;
    }
    return sum;
}

int main(){

    int n1,n2,t;
    cout<<"Enter no. of digits in 1st, 2nd number"<<endl;
    cin>>n1;
    cin>>n2;

    cout<<"Enter digits of no 1:"<<endl;
    while(n1>0){
        cout<<"Enter digit at "<<n1<<":"<<endl;
        cin>>t;//Have to check if single digit
        struct Node temp(t);
        insert(head1, temp);
        n1--;
    }
    cout<<"no1(rev):"<<endl;
    print(head1);//Not throwing Error!!!

    cout<<"Enter digits of no 2:"<<endl;
    while(n2>0){
        cout<<"Enter digit at "<<n2<<":"<<endl;
        cin>>t;//Have to check if single digit
        struct Node temp(t);
        insert(head2,temp);
        n2--;
    }
    cout<<"no2(rev):"<<endl;
    print(head2);//Not throwing Error!!!

    cout<<"sum"<<endl;
    s = add(head1,head2);
    cout<<"Verifying s is sum:";
    cout<<s->digit;
    cout<<s->next->digit;
    cout<<s->next->next->digit;
    cout<<s->next->next->next->digit;
    cout<<endl;
    print(s);// This is throwing Error!!!
    return 0;
}

以下是使用 valgrind 的输出:

> valgrind --leak-check=yes ./LinkedListAdd.out
> 
> ==8070== Memcheck, a memory error detector
> ==8070== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
> ==8070== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
> ==8070== Command: ./LinkedListAdd.out
> ==8070==  
> Enter no. of digits in 1st, 2nd number 
> 3 4 
> Enter digits of no 1:             
> Enter digit at 3: 
> 5 
> Enter digit at 2: 
> 6 
> Enter digit at 1: 
> 7
> no1(rev): 
> Print:  
> 765 
> Enter digits of no 2: 
> Enter digit at 4: 
> 5 
> Enter digit at 3: 
> 6 
> Enter digit at 2: 
> 7 
> Enter digit at 1: 
> 8 
> no2(rev): 
> Print: 
> 8765 
> sum
> ==8070== Conditional jump or move depends on uninitialised value(s)
> ==8070==    at 0x4009B9: insert(Node*&, Node&) (LinkedListAdd.cpp:20)
> ==8070==    by 0x400AD2: add(Node*, Node*) (LinkedListAdd.cpp:43)
> ==8070==    by 0x400D92: main (LinkedListAdd.cpp:92)
> ==8070==  
> Verifying s is sum:6245 
> Print: 
> ==8070== Conditional jump or move depends on uninitialised value(s)
> ==8070==    at 0x400A29: print(Node*) (LinkedListAdd.cpp:28)
> ==8070==    by 0x400E32: main (LinkedListAdd.cpp:99)
> ==8070== 
> ==8070== Use of uninitialised value of size 8
> ==8070==    at 0x400A0A: print(Node*) (LinkedListAdd.cpp:29)
> ==8070==    by 0x400E32: main (LinkedListAdd.cpp:99)
> ==8070== 
> ==8070== Use of uninitialised value of size 8
> ==8070==    at 0x400A1C: print(Node*) (LinkedListAdd.cpp:30)
> ==8070==    by 0x400E32: main (LinkedListAdd.cpp:99)
> ==8070== 
> ==8070== Invalid read of size 4
> ==8070==    at 0x400A0A: print(Node*) (LinkedListAdd.cpp:29)
> ==8070==    by 0x400E32: main (LinkedListAdd.cpp:99)
> ==8070==  Address 0x750000800003f7da is not stack'd, malloc'd or (recently) free'd
> ==8070== 
> ==8070== 
> ==8070== Process terminating with default action of signal 11 (SIGSEGV)
> ==8070==  General Protection Fault
> ==8070==    at 0x400A0A: print(Node*) (LinkedListAdd.cpp:29)
> ==8070==    by 0x400E32: main (LinkedListAdd.cpp:99) 6245-1064971727==8070== 
> ==8070== HEAP SUMMARY:
> ==8070==     in use at exit: 176 bytes in 11 blocks
> ==8070==   total heap usage: 11 allocs, 0 frees, 176 bytes allocated
> ==8070== 
> ==8070== LEAK SUMMARY:
> ==8070==    definitely lost: 0 bytes in 0 blocks
> ==8070==    indirectly lost: 0 bytes in 0 blocks
> ==8070==      possibly lost: 0 bytes in 0 blocks
> ==8070==    still reachable: 176 bytes in 11 blocks
> ==8070==         suppressed: 0 bytes in 0 blocks
> ==8070== Reachable blocks (those to which a pointer was found) are not shown.
> ==8070== To see them, rerun with: --leak-check=full --show-leak-kinds=all
> ==8070== 
> ==8070== For counts of detected and suppressed errors, rerun with: -v
> ==8070== Use --track-origins=yes to see where uninitialised values come from
> ==8070== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0) Segmentation fault

请帮助我了解可能出了什么问题/将我引导到可能有助于我理解的资源。

名称

你永远不会初始化sum指针:

struct Node* add(struct Node* head1, struct Node* head2){
    struct Node* sum;   // <<<<< uninitialized
    ...
    while(head1!=NULL && head2!=NULL){
        ...
        insert(sum,t);  // <<<<< undefined behaviour within

(可能还有其他问题,但这是最明显的问题。)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章