2014-03-02 3 views
0

Итак, я пытался конвертировать BST в DLL, используя некоторые заданные функции, которые мне пришлось использовать. Делая это, я продолжал получать ошибки сегментации. Когда я попытался отладить его, я, наконец, пришел к этому. Я написал очень простой тестовый сценарий ниже.C++ проблемы с указателями при создании узлов

То, что я знал о указателях, передается по ссылке, так как в том случае, если я изменяю значение/объект, к которому указывает переданный указатель, он отражается в моей исходной функции вызова.

Почему это происходит, когда я создаю новый узел, а затем передаю указатель (myf), он работает, но когда я просто передаю указатель и создаю новый узел внутри функции, он показывает ошибку сегментации (myf2)?

Если это связано с тем, что новый узел выходит из сферы действия, снова проверьте функцию «myf». Я создал новый узел, на который указывает мой оригинальный узел. И значение этого сохраняется после завершения вызова функции. Разве это тоже не выходит за рамки?

У меня есть некоторые основные фундаментальные проблемы с указателями, которые появляются, и это действительно поможет. Благодаря

#include<iostream> 
using namespace std; 

class Node 
{ 
public: 
    int val; 
    Node *left; 
}; 

void myf(Node *a) 
{ 
    a->left = new Node(); 
    a->left->val = 20; 
    a->val = 15; 
} 

void myf2(Node *a) 
{ 
    a = new Node(); 
    a->val = 35; 
} 

int main() 
{ 
    Node *a = NULL, *b = NULL; 
    a = new Node(); 
    a->val = 5; 
    myf(a); 
    cout << "New value of a = " << a->val << endl; 
    cout << "left value of a = " << a->left->val << endl; 
    myf2(b); 
    cout << "New value of b = " << b->val << endl; 
} 
+0

где указатель 'right'? –

+0

Игнорируйте скобки, которые я дал после узла(). При инициализации не требуется. – user3370135

+0

Привет Rikayan. Это тестовый код. Никакой логики или мотивов этой программы. Я был в середине более сложного кода, поэтому я написал этот тестовый код, чтобы найти, что происходит не так. Пожалуйста, сосредоточьтесь на том, что здесь. Благодарю. – user3370135

ответ

0

Почему, когда я создаю новый узел, а затем передать указатель (MYF), он работает,

Node * a: main() заставляет его указывать на блок памяти, вы передаете этот адрес myf, вы обновляете память в этом блоке. Оно работает!

Но когда я просто передаю указатель и создаю новый узел внутри функции, он показывает ошибку сегментации (myf2)?

Node * б: main() не присваивает ему ничего, это указывает на NULL, myf2() получить только адрес, который NULL, вы создаете другой указатель b (не то же самое, что и в main()) , укажите, что он указывает на некоторый блок памяти, но он не обновляет то, что указывает ваш исходный b в main(), который по-прежнему указывает на NULL. Следовательно, SEGFAULT.

По сути вы пытаетесь два различных действительных подходов, это правильный путь:

Случай 1.

main() 
{ 
    Node* a = NULL; 
    a = new Node(); //make 'a' point to some valid block of memory 
    myf(a); // here you are passing the address of the memory block of type Node 
    cout << "New value of a = " << a->val << endl; //and this is valid since 'a' points to a valid address 
} 

void myf(Node *a) 
{ 
    a->left = new Node(); 
    a->left->val = 20; // Since the address that you got here is valid, you can make changes here, and in main() Node* a is aware of this address 
    a->val = 15; 
} 

Случай 2.

main() 
{ 
    Node* b = NULL; 
    myf2(&b); // here since b points to NULL, you have to send the address where this NULL is stored so that the called functon can upadte this NULL to something meaningful 
    cout << "New value of b = " << b->val << endl; // this is correct, because we changed what 'b' pointed to from NULL to a valid block of memory of type 'Node' 
} 

void myf2(Node **a) //It is a double pointer here because you need to update what it points to, curently it holds NULL 
{ 
    *a = new Node(); // Make it point to a valid address, remember main() has track of 'a', 
    *a->val = 35; // Now if you make any changes to the blok that 'a' points to, main() will have account of it 
} 
+0

Объяснение было действительно тем, что я искал. Большое спасибо. Делает смысл. Но когда внутри myf, я создаю новый узел для b-> left, я тоже не меняю адрес?Почему это отражается? – user3370135

+0

см. Обновленный комментарий. Переменная b в основном и в вашем fn myf2 не является одинаковой. – brokenfoot

+0

Надеюсь, что обновленный ответ поможет, прокомментируйте, если у вас все еще есть сомнения. – brokenfoot

1

Ваша проблема, ваш указатель не установлен б, чтобы сделать это, вам нужно отредактировать myf2 к чему-то вроде этого:

void myf2(Node **a) 
{ 
    *a = new Node(); 
    (*a)->val=35; 
} 


И называть myf2 так:

myf2(&b); 


И это должно решить вашу проблему, я считаю.


Не думайте Node *b только как указатель, думать об этом как целое число, а также, потому что это то, что указатель рассыпается на целое число указывает на пространство в памяти.

Итак, вы передаете указатель указателя (целого) на функцию.

Другой пример:

void myfunction(int *i) { 
    *i = 5; 
} 

int main(int argc, char** argv) { 
    int x; 
    myfunction(&x); 
    cout << x << endl; 
    return 0; 
} 

Но что использует фактическое число.

+0

Привет, Дэвид. Но * внутри myf2 в основном по-прежнему является указателем на объект? Как вы назначили ему узел? – user3370135

+0

@ user3370135 Да, это указатель, вы должны выделить объект Node для '* a', как показано в примере. 'a' является указателем на указатель, а' * a' является самим указателем. '(* a) = new Node();' –

+0

@ user3370135 Я назначил ему узел, передав mem-адрес самого указателя, который большинством операционных систем является «integer», и я сохранил недавно выделенный объект в памяти указателя, переданного функции. –

0

Вы должны вернуть ссылку на Node *a, к которому вы динамически распределяемой памяти ..

Node* myf(Node *a) 

{ 

    a->left = new Node(); 

    a->left->val=20; 

    a->val=15; 

    return a; 
} 

В main()

a = myf(a);

ранее a в main() не указывает на память, выделенную в myf() ...

+0

Привет, Hade. Хороший ответ. Но на самом деле мне нужно вернуть пустоту, поскольку я использую функцию рекурсии, и есть другие факторы. Я думаю, что ответ Дэвида ниже будет работать хорошо. Я полностью забыл про передачу по ссылке. В любом случае, спасибо за ваши усилия. – user3370135

+0

не проблема ... ;-) – HadeS

0

Получите Node ptr по ссылке ниже.

void myf2(Node *&a) //<-- Notice & in function signature. 

В текущем коде, вы передаете a (Node*) по значению, поэтому любые изменения, сделано в функции не будут отражать вне функции и доступа к b->val (null доступ PTR) будет ошибка сегмента

Смежные вопросы