-3

so right now i am trying to do some nift code for a little game i am making and I've run into something that has been bothering me for a while about pointers.

but first things first, i am trying to have a function take in a void* and give that void* a value, but it seems to not actually stay beyond the function like i'm used to. so...

void ItemGen(void* Holder){

    Item* NewItem
    NewItem = new Item*
    NewItem->Init();
    Holder = NewItem;

}

it's not actually making "items" but various kinds of items that inherit from a item, this is just me making it simpler.

Holder gets changed but never make it outside the function, how should i change this, so that it does.

on top of that, i am sort of confused about a certain occurrence that can happen and i just want to know what happens when you do these. or really the difference between them

void *p1;
void *p2;
&p1 = &p2;
p1 = p2;
*p1 = *p2;

oh and is there a way to do a XOR operation on pointers so i can swap them with out a holding pointer.

i feel like i asked very stupid questions, but are confusing simply because they're void *'s.

  • 1
    Also, there are many immediate syntax problems in your code. Missing semicolons, type-incorrect assignments (`NewItem = new Item*`). Why not try compile some of this and work your way through the error messages before posting. – jogojapan Jun 21 '13 at 01:49
  • There are 3 great hurdles when learning to program: flow control (loops, recursion, and functions), indirection (references and pointers), and concurrency (threads, processes, and synchronization). Welcome to hurdle 2. I hope you passed 1 already. :) – Yakk - Adam Nevraumont Jun 21 '13 at 02:53

3 Answers3

0

Pointers are variables like any other, and as such are passed by value to functions. You've simply assigned a new value to the parameter copy of your pointer.

If you want to change a variable you pass to a function you must pass by reference or by pointer. Preferably the former.

void ItemGen(void *& Holder);

BTW, that's a horrible naming convention.

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
0

I am answering this point "Holder gets changed but never make it outside the function, how should i change this, so that it does."

void ItemGen(Item** Holder){
 Item* NewItem
 NewItem = new Item*
 NewItem->Init();
 *Holder = NewItem;
}

void someotherfunc() {
 Holder * holder=0;
 ItemGen(&holder)
 if(holder!=0) {
      holder->dosomething()
  }

}

Anand Rathi
  • 790
  • 4
  • 11
0

"void" simply means "nothing". A "void*" pointer points to nothing in particular. It's a way of saying "I don't know what kind of thing this pointer points to"; a void* pointer is a catch all that can receive any kind of pointer, but if you want to go from a void* pointer to any other kind, you have to explicitly cast it.

As to your first problem:

If you lived at "1234 Pointer Street", there is nothing magical about the number "1234", it's just a number. It only tells you anything when you treat it as a "pointer" - a house number. It "points" to a house on a particular street.

In the case of a computer, the street is memory.

int a = 0;
int* b = 0;

the variables "a" and "b" both contain the numeric value "0".

b = b + 1;

See? perfectly valid. So

void foo(int a, int* b)
{
    a = a + 1;
    b = b + 1;
}

void bar()
{
    int x = 0;
    int* y = 0;
    foo(x, y);
    // 'x' and 'y' are still zero here, they have to be, or you couldn't do
    foo(0, 0);
}

Pointers to have some distinguishing features from regular variables.

int a = 0;
int* b = 0;

a = a + 1; // now a = 1
b = b + 1; // now b = b + sizeof(int) => 4.

What pointers do best is provide values for C/C++'s "dereference" operators.

a = *(b);

Going back to the streets example, if we assigned b our "1234 Pointer Street" address, it would be:

b = 1234;

What if we wanted to deliver something there?

*b

This means: The contents of the address that b describes.

Lets go back to the definition

int* b;

This says: "b is the address of an integer". How do we get the address of a specific integer?

// imagine a set of mailboxes.
int box1, box2, box3, box4, box5;

// lets put something interesting into box 3.
box3 = 5;

// now let's address somethign to box3.
// "&" is the "address of" operator.
int* pointer = &box3;

// now lets put something more interesting in pointer.
pointer = 10;
// whoops - that was wrong, we just changed the ADDRESS to some random numeric value.
// what we mean't was:
*pointer = 10;

printf("box 3 contains %d\n", box3);
// answer? 10, not 5.

After setting "pointer = &box3" we populated "pointer" with the location of box3's storage in memory, so when we wrote to that address using "*pointer = 10" we wrote to the storage address of box3.

You asked about void *p1; void *p2; &p1 = &p2; p1 = p2; *p1 = *p2;

"&p1 = &p2" says "the address of p1 is the address of p2" and isn't legal, it wouldn't compile.

"p1 = p2" is legal, but it says "assign the same address as p2 to p1"

"*p1 = *p2" is illegal because you are using void pointers, which point to void, besides, you've just made p1 and p2 be equal to each other so it would be a null operation.

To fix your initial problem, you would need to provide a way for the caller to receive the new value you are creating.

Option 1: Accept a pointer-to-pointer

This is the very old-school C way to do it, but your code doesn't look very C++ so far so I'll list it first.

void ItemGen(void** Holder)
{
    Item* NewItem = new Item;
    NewItem->Init(); // why doesn't the constructor do this?
    // ** means pointer to storage that is itself also a pointer,
    // so if we dereference it once we will be refering to the inner pointer.
    *Holder = NewItem; 
}

Option 2: Return a pointer

void* ItemGen() // Why isn't this "Item*"?
{
    Item* NewItem = new Item;
    NewItem->Init();
    return NewItem;
}

Option 3: Take a reference

void ItemGen(Item*& Holder)
{
    Holder = new Item;
    Holder->Init();
}

This says "Holder is a reference to a pointer to storage of type Item". It's exactly like a "Item*" pointer except instead of creating a temporary local copy of the value passed in, it's an alias for the value that was passed in.

If you absolutely have to throw away the type information of your pointer:

void ItemGen(void*& Holder)
{
    Item* NewItem = new Item;
    NewItem->Init();
    Holder = NewItem;
}

At the level you appear to be with C++ so far, I would guess that your use of void* pointers is probably misguided.

kfsone
  • 23,617
  • 2
  • 42
  • 74