Noch ein Pointerproblem c++

tanj

New member
Moin,

folgendes Problem:
Es wird Anker uebergeben, und Anker wird innerhalb der Funktion veraendert.
Wenn ich dann aber auf Anker zugreifen will, steht noch der alte Werte (also 0) im Pointer. Wenn ich funktion anstatt als Rueckgabetyp "void" mit "listeNode*" versehe und mir Anker zurueckgeben lasse funktioniert es wie es soll. Wieso ist das so? Wenn ich das gleiche z.B. mit einem int* anstatt listNode* mache funktioniert es wie gedacht?
Code:
 struct listNode
    {
        int data;            //  data
        listNode *next;  //  next node
    };
listNode* Anker = 0;
obj.funktion(Anker)
 

benediktibk

Standardgruppe für nicht aktivierte User
Bitte ein bisschen mehr Code.

mfg benediktibk
 

blue182

Stammuser
Moin,

folgendes Problem:
Es wird Anker uebergeben, und Anker wird innerhalb der Funktion veraendert.
Wenn ich dann aber auf Anker zugreifen will, steht noch der alte Werte (also 0) im Pointer. Wenn ich funktion anstatt als Rueckgabetyp "void" mit "listeNode*" versehe und mir Anker zurueckgeben lasse funktioniert es wie es soll. Wieso ist das so? Wenn ich das gleiche z.B. mit einem int* anstatt listNode* mache funktioniert es wie gedacht?
Code:
 struct listNode
    {
        int data;            //  data
        listNode *next;  //  next node
    };
listNode* Anker = 0;
obj.funktion(Anker)

Wenn das alles ist an Code, dann ist die Antwort recht einfach ...
Das Objekt Anker gibt es noch gar nicht. Du musst es zuvor allozieren und dann uebergeben.

Merke dir:
- Funktionen, die Speicher allozieren, muessen die Speicheradressen zurueckgeben.
- Funktionen, die Speicher veraendertn sollen, muessen bereits allozierte Objekte uebergeben bekommen. Im Regelfall geben diese Funktionen die Adresse des veraenderten Objekts zurueck - muessen es aber nicht!

Code:
typedef struct _listNode {
    int data;            //  data
    listNode *next;  //  next node
} listNode, *pListNode;

pListNode foo_create() {
    pListNode node = (pListNode)malloc(sizeof(listNode));
    return node;
}

pListNode foo_mutate(pListNode node) {
    node->data = 4711;
    return node;
}

[...]

pListNode node = foo_create();
node = foo_mutate(node);


Btw ... ich hoffe damit dein Problem getroffen zu haben. Leider ist deine Frage aufgrund mangelndes Beispielcodes etwas schwierig nachzuvollziehen.
 
Zuletzt bearbeitet:

tanj

New member
na ich wollte jetzt nicht den ganzen Code posten, ist etwas laenger...
Aber gut:
Code:
Betreffender Abschnitt aus der main:
if (argc == 3)
    {
        Intersect inter; //= new Intersect();
        Intersect inter2;// = new Intersect();
        listNode* Anker = 0;
        inter.parseSetOfIntegers(argv[1]);
        inter2.parseSetOfIntegers(argv[2]);
        if (inter.size() == 0 || inter2.size() == 0)
        {
            printf("Computing points of intersection with an empty set is "
                    "impossible.\n");
        }
        else
        inter.intersectTwoSetsOfIntegers(&inter2, Anker);
      //  printf("Klappe die zweite %i\n", Anker);
       // print(inter.intersectTwoSetsOfIntegers(&inter2, Anker));
    }
Betreffender Abschnitt aus Intersect.h
Code:
//  List to store a not know number of integers.
    struct listNode
    {
        int data;            //  data
        listNode *next;  //  next node
    };

class Intersect
{
 private:
    int _size;

    listNode* _elements;
 public:
    static int numObjectsCreated;
    //  Constructor
    Intersect();

    //  Constructor includes init of _elements and size
    Intersect(listNode* elements);
    FRIEND_TEST(ListProcessingTest, constructor);
    //  Destructor
    ~Intersect();
    //  Function parseSetOfIntegers <listAsString>,
    //  prase a String list to an integer list.
    void parseSetOfIntegers(const char* listAsString);
    FRIEND_TEST(ListProcessingTest, parseSetOfIntegers);
    //  Function intersectTwoSetsOfIntegers <Intersect inter, listNode*  Anker>
    //  computes points of intersection of two sets.
   void intersectTwoSetsOfIntegers(Intersect* inter, listNode* Anker);
   
    FRIEND_TEST(ListProcessingTest, intersectTwoSetsOfIntegers);

    
    int size();

    listNode* getElements();
    void setElementsNext(listNode* node);


};

void print(listNode* Anker);
Und dazu noch die intersectTwoSetOfInteger aus Intersect.cpp
Code:
void Intersect::intersectTwoSetsOfIntegers(Intersect* obj, listNode* Anker)
{
    listNode* first = ((*obj).getElements());
    while(_elements)
    {  
        int j = 0;
        while((*obj).getElements() && j < (*obj).size() )
        {
           if (_elements -> data == ((*obj).getElements())  -> data)
            {
                listNode *node = new listNode;
                node -> data = _elements -> data;  //  Include data
                node -> next = Anker;  //  concaternate old list
                Anker = node;
                j = (*obj).size();
            }
            (*obj).setElementsNext(((*obj).getElements()) -> next);
        }
        _elements = _elements -> next;
        (*obj).setElementsNext(first);
    }
}

Wenn jetzt inter.intersectTwoSetsOfIntegers(&inter2, Anker); in der Main aufgerufen wird, ergibt sich das im Anfangspost beschriebene Problem.
 

benediktibk

Standardgruppe für nicht aktivierte User
Wenn ich das jetzt richtig verstanden habe liegt das Problem darin, dass du einen Pointer auf einen Pointer benötigst. Du übergibst beim Aufruf von intersectTwoSetsOfIntegers einen Pointer auf ein Objekt. Was du dann intern damit machst, ist aber im Endeffekt nur, dass du den temporären Pointer auf ein anderes Objekt zeigen lässt, was der externe Aufrufer natürlich nicht mit bekommt.

Code:
void function(Object **object)
{
   *object = new Object();
}

void main()
{
   Object *object = NULL;

   function(&object);

   // object != NULL
}

Natürlich ungetestet, aber die Idee dahinter sollte verständlich sein. Ist aber vom Konzept her bedenklich, unter Umständen wäre ein grundlegend anderes Design besser.

mfg benediktibk
 
Oben