Advertisement

Modyfing pointers

Started by May 30, 2018 09:57 AM
6 comments, last by Gnollrunner 6 years, 3 months ago

I once again went into the issue, only to find out that i don't remember anything and don't understand something that was for me obvious once.


void AddNextCSG(TCSGInfo * first, TCSGInfo * to_add)
{
	TCSGInfo * p = first;
	if (p == 0)
	{
	ALOG("ADDING AS FIRST CSG");
	first = to_add;
	}
	else 
	{
		ALOG("ADDING AS NEXT CSG");
		p = GetLastCSG(first);
		p->next = to_add;
	}
}

TCSGInfo * GetLastCSG(TCSGInfo * first)
{
	TCSGInfo * p = first;
	while (p!=0)
	{
		if (p->next == 0) return p;
		p = p->next;
	}

return 0;
}

Take a look at AddNextCSG function the phrpose was just to add another element to a linked list, however instead of adding nothing happens, but wheb i pass the first object as pointer to a reference it gets modified, but actually why i cant just use such simple some_pointer->value = something; type


TCSGInfo * csg_output = 0;

for (int i=0; i < model->FaceLength; i++)
{
	TCSGInfo * csgout = new TCSGInfo();

	AddNextCSG(csg_output, csgout);
}

I get ADDING AS FIRST CSG" all the time

Do i have to dereference a pointer? 

    TCSGInfo * p = first;
    if (p == 0)
    {
    ALOG("ADDING AS FIRST CSG");
   (* first) =(* to_add);
    }

 

This is exactly what im trying to avoid.

Thia code above has no sense when first is null anyway even if it wasnt null it has no sense i dont need to copy values from one to another but want that first points on newely created pointer that points on a newely created structure !!! :(

 

Maybe this is because TCSGInfo holds three structures with overloaded = operator, but still TCSGInfo has no overloaded operators at all and when i point one onto another the one should become another

I'm not sure what you want to do, but maybe using a reference to pointer does what you want - try:

void AddNextCSG(TCSGInfo* &first, TCSGInfo * to_add)

It's maybe less cumbersome / better to read than using pointer to pointer.

Advertisement

Basically

int * p = 0;

int * k = new int[1];

(*k) = 3;

And i want p = k; and that does not do it

Im asking cause i just rewrite a code and it just got really nasty, doesnt provide me correct results and i found that i have a problem with those pointers and this is only one function out if 20 i need to recheck but hiw im supposednto recech something when i have no idea how to fix this lol, and yes i did earlier what you wrote it started to assign first object (didnt run tests if linked list is connected correctly) however i have such code in 15 more places which does not invlove calling something similar to AddNextCSG func but also assigns p = k; when p is 0, or i want to remove something from linked list like

 



inline void RemoveEntity(TEntity *p, TEntity * first_object)
{

if (p == 0) return;


if (p->prev == 0) //deleting first object
{
if (p->next != 0) p->next->prev = 0;
first_object = p->next;
delete p;
return;
}


if ( (p->prev != 0) && (p->next == 0) )      //last
p->prev->next = 0;


if ( (p->prev != 0) && (p->next != 0) )
{
p->prev->next = p->next;
p->next->prev = p->prev;
}




delete p;
}

So i ask why and how to use that, and why not how i use it.

Anyway

(*p)->next = some other pointer - seems like a correct way to do it but i still dont get it 

This is C code (even if it's written in C++).  I C, all function parameters are passed by value.  You're passing the pointers by value.  That means they get copied in, and then on function exit get destroyed.

If you're trying to have the side effect of modifying an argument passed to a function, then you must either pass it by pointer (for C or C++) or by reference (in C++).  That means you function either need to be this (C or C++)

void AddNextCSG(TCSGInfo** first, TCSGInfo* to_add);

or this (C++ only).

void AddNextCSG(TCSGInfo*& first, TCSGInfo* to_add);

And yes, in the first case you need to dereference the pointer-to-pointer when assigning to it.

Stephen M. Webb
Professional Free Software Developer

1 hour ago, KKTHXBYE said:

Basically

int * p = 0;

int * k = new int[1];

(*k) = 3;

And i want p = k;

Yes, you can do this as proposed:


	void Foo (int* &pointer, int *h) // notice the additional & so we use pointer itself, not a copy
{
    pointer = h;
}
	int five = 5;
int *p = 0;
int *q = &five;
Foo (p, q);
	// now p points to five as well
	

 

Or using pointer to pointer:


	void Foo (int* *pointer, int *h) // notice the additional & so we use pointer itself, not a copy
{
    (*pointer) = h;
}
	int five = 5;
int *p = 0;
int *q = &five;
Foo (p, q);
	// now p points to five as well
	

ah was hard to find that topic, thanks all, second reply clarified everything, I know what to do now, thanks again topic to ve closed, joej you too helped dont worry

Advertisement

RemoveEntry actually looks more or less correct (although I'd have to run it to be sure) . It's a doubly linked list. However there are a few things.......

First after the function returns p will still have a value. But it will be invalid, i.e. the memory for it will be "gone girl" and if you try to use it, likely your program will crash. This is OK in a certain style of programming (as long as you don't use p). Some people may yell at you but some old timers like myself will be OK with it.  That being said if you want p to be gone outside the function you need to pass it by reference (TEntity *&p) and then in the code before you return but after the delete set it to zero (p=0).  Remember you return in 2 places so you need to do it twice.

Third this is a very sub-optimal way to implement a doubly linked list unless you are doing something special. I mean look at all the ifs. You even have some extra checks which are not necessary because you actually checked those conditions before but that's not my point. You don't need any ifs at all, if you change it up a bit. Make the list circular.  Make the next pointer of the of the last item in the list point to first_object, and make the prev pointer of first_object point to the last item in the list. Then you can just do:

p->next->prev = p->prev;
p->prev->next = p->next;
delete p;

and if you want

p = 0;

Now you don't even need to pass in first_object because p can actually remove itself :)

So moving on let's talk a little more about your d-list .....

If it's circular to initialize it make it point to itself.

first_object->next = first_object;
first_object->prev = first_object;

now to add p to the front of the list just do:

p->next = first_object->next;
p->prev = first_object;
first_object->next->prev = p;
first_object->next = p;

and if you want to add to the end of the list:

p->prev= first_object->prev;
p->next = first_object;
first_object->prev->next = p;
first_object->prev = p;


If you make your list circular your whole life becomes a lot easier.

This topic is closed to new replies.

Advertisement