Archived

This topic is now archived and is closed to further replies.

so whats the deal with pointers and assignment?

This topic is 5501 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

for example, the code:
void routine(*ptr)
{
   ptr=~ptr;
   return;
}
 
would cause all kinds of weird shit to happen, however
void routine(*ptr)
{
   int a;
   a=~ptr;
   ptr=a;
   return;
}
 
works perfectly (assigns the 1''s compliment of a variable to that variable via a pointer) is this a compiler thing, or am i missing somthing? - Twisted Matrix

Share this post


Link to post
Share on other sites
It doesn''t look like you''re dereferencing the pointer anywhere - would the functions have any external effect at all?

Also, the "return" statements are totally unnecessary.


Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions

Share this post


Link to post
Share on other sites
quote:
Original post by TwistedMatrix
would cause all kinds of weird shit to happen

No kidding. You haven''t given the pointer a type, so it shouldn''t get past the compiler. Weird shit, man. If you give the pointer a type, it still shouldn''t compile, since the complement operator is defined to operate on integral types, but not pointers. Care to show us the real code?

Share this post


Link to post
Share on other sites
Heres the problem. I have an array of structures. I know how to pass a pointer to a function and address it indirectly

example:

void dosomthing(struct junk *aryptr)
{
if (aryptr[10]->a == 21) {aryptr[43]->c=1; }
//..ect ect
}
int main()
{
struct junk
{ char a;
int b;
short int c;
unsigned char data[10];
} array[50];
dosomthing(&array[0]);
return 0;
}


This far i am right im pretty sure. could somebody give me an example of the difference between only passing a pointer to one element and passing a pointer that allows the function to acess all the elements?

you would use "struct junk **aryptr" correct?

also, how would you pass that pointer from dosomthing() to another function if you wanted to? This is giving me alot of trouble. I thought I knew pointers but I guess I was wrong.

- Twisted Matrix

Share this post


Link to post
Share on other sites
Just pass the array normally. Arrays aren''t passed by value, they are always passed by reference. So just pass it like this:

void main()
{
int array[20];
SomeFunc( array );
}

void SomeFunc( int * array )
{
//do whatever you need to do with it in here.
}

and you don''t have to return the array, because it''s just pointing to the same place in memory.

Share this post


Link to post
Share on other sites
Pointers and arrays are virtually the same thing.

quote:

dosomthing(&array[0]);



This is correct, although it''s not the nicest way to do it.

Other ways include dosomthing(array+0); or just plain dosomthing(array);.

If you haven''t done addition or subtraction on a pointer, what happens is that it creates a new pointer of the same type offset by that many bytes times the size of whatever the pointer is of.

Why the heck is that useful? Well, you can do silly things like this:

  
#include <iostream>

void printstring(const char *string)
{
while(*string != NULL) // while we aren''t pointing to a null character.

{
cout << *string; // print the character

++string; // and move the pointer to the next character.

}
}

int main(void)
{
printstring("Hello World");
return 0;
}


You can also use a pointer as an array with only one element, like this:


  
#include <iostream>

int main(void)
{
int * number = new int; // create a pointer to a number


number[0] = 5; // set element 0 to 5.

cout << number[0] << endl; // display element 0.


delete number; // delete the pointer


return 0;
}


Alas, pointers and arrays are not 100% the same. (They were in C, but the introduction of classes and destructors screwed us.)

  
int main(void)
{
int * pointer = new int; // create a pointer

int * array = new int[1]; // create an array


delete pointer;
delete [] array;
return 0;
}


We have to do something special with the array because otherwise only the destructor for the first object in the array gets called. How does delete know how many elements are in the array? It depends on the compiler, but one common way is this:

New allocates the memory needed, plus a few bytes. The first few bytes are used to store the number of elements in the array, it calls the constructors for all the objects, and returns a pointer a few bytes ahead of the memory it allocated.

When you delete an array, delete will look behind the address you have it to find out how many elements it needs to destroy, calls their destructor, and then frees the memory.

You didn''t really need to know that, but I wanted you to know why it''s important to use the right one, because the compiler will probably let you do both.

Share this post


Link to post
Share on other sites
quote:
Original post by smart_idiot
Pointers and arrays are virtually the same thing.

No they''re not!
quote:

Alas, pointers and arrays are not 100% the same. (They were in C, but the introduction of classes and destructors screwed us.)

Pointers and arrays are *not* the same thing in C either - they''re exactly the same things as in C++. What makes you think classes and destructors change what they are? An array is a contiguous region of storage sufficiently big to contain n elements of a single type, whereas a pointer is just that: a pointer.

Share this post


Link to post
Share on other sites
Yeah, that is a common misconception of a lot of people who are starting to program, though I can't really see why. Pointers and arrays aren't really related at all -- except superficially. An array is just a "row" of a bunch of data of the same type. The only relationship between arrays and pointers is that when you use the name of an array in an expression, it represents a pointer to the first element (in most cases).

That doesn't mean that an array is a pointer, much in the same way that when you use a function with a return type of a pointer to an int in an expression doesn't make the function itself a pointer to an int. It just simply returns that value.

Example:

int* const SomeFunction(); // Declaration of a function

...

*SomeFunction() = 2; // Sets the integer to 2



int SomeArray[10]; // Declaration of an array

...

*SomeArray = 2; // Sets the first element to 2

In those expressions, I don't know anyone who would say that SomeFunction itself is a pointer to an int, however, a lot of beginners seem to call SomeArray itself a pointer to an int. I don't really see why it's such a common misconception, but relating it to a function return type is the best why that I can try and explain how they are related. It's not exactly the same, but if you understand what's going on with the function call then you should be able to similarly understand what's going on with the use of the array name. If you want to extend the analogy with the function, using an array name "returns" a pointer to its first element. Other than that, they aren't related at all.

[edited by - Matt Calabrese on November 20, 2002 2:41:23 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by smart_idiot
Pointers and arrays are virtually the same thing.



I hope I never run any of your software on my computer.

Share this post


Link to post
Share on other sites
Well, my compiler can't seem to tell the difference, but maybe it's broken. Please enlighten it as to why it shouldn't be compiling this program (besides that it was written by me):


        
#include <iostream>

#include <cstdlib>


// This does stuff to pointers.

void func1(int * foo) // A function using a pointer

{
++foo;
--foo;
*foo = 1;
foo[1] = 2;
*(foo+2) = 3;
(foo+1)[2] = 4;
}

// Hey, this looks exactly like func1!!!!

void func2(int foo[4]) // A function using an array

{
++foo;
--foo;
*foo = 1;
foo[1] = 2;
*(foo+2) = 3;
(foo+1)[2] = 4;
}

// Don't the function's signatures need to be the same to do this? Why is this working?

void (*func[2])(int foo[4]) = {&func1, &func2};
// This works too if you want to uncomment it and try it.

// void (*func[2])(int *foo) = {&func1, &func2};


// A nice unbiased way to show each type.

template <class T> void ShowElements(T var)
{
cout << var[0] << ' ' << var[1] << ' ' << var[2] << ' ' << var[3] << endl;
}

int main(void)
{
// A fitting way to display the title.

char array_text[7] = "Arrays";
char *pointer_text = "Pointers";
cout << array_text << " and " << pointer_text << endl;

// An array

int foo1[4];
// A pointer (using malloc to ignore constructors and show there is nothing special happening)

int *foo2(static_cast<int *>(malloc(sizeof(int)*4)));

func[0](foo1); // using an array as a pointer.

ShowElements(foo1);

func[1](foo1); // using an array as an array.

ShowElements(foo1);

func[0](foo2); // using a pointer as a pointer.

ShowElements(foo2);

func[1](foo2); // using a pointer as an array.

ShowElements(foo2);

free(foo2); // free the data we're pointing to.


cin.get(); // Wait for the user to press a key.

}


[edited by - smart_idiot on November 20, 2002 11:58:01 PM]

Share this post


Link to post
Share on other sites
Quick related question, what the heck does the ''~'' in the orginal post do? I''ve never heard of that as an operator, and as far as I was aware, it''s only used to preface destructors.

Share this post


Link to post
Share on other sites
quote:
Original post by smart_idiot
Well, my compiler can''t seem to tell the difference, but maybe it''s broken. Please enlighten it as to why it shouldn''t be compiling this program (besides that it was written by me):
....(long code)...

Try replacing ''int'' with ''void'' and see if it really compiles.

Share this post


Link to post
Share on other sites
quote:
Original post by smart_idiot
Well, my compiler can''t seem to tell the difference, but maybe it''s broken. Please enlighten it as to why it shouldn''t be compiling this program (besides that it was written by me):


You don''t know the language well enough:

void func2(int foo[4]);

Does not make a function that takes as a parameter an array of length 4. It makes a function that takes a pointer to an integer. In fact, that 4 in your declaration means absolutely nothing. The same exact declaration can be done with:

void func2(int* foo);

and

void func2(int foo[]);

Why? First, remember that arrays don''t have copy constructors, which should have been your first tip off, so obviously from the start the function declaration couldn''t be doing what you''d think it''s doing from what you wrote out. The reason that C++ provides the syntax

int foo[]

is so that the person reading the function declaration can clearly see that an array is meant to be passed via a pointer to the first element. If you just used

int* foo

It won''t be as clear from the start that you want an array to be passed.

If you REALLY wanted to test out if arrays and pointers were the same you could do make 2 different functions -- one which takes a reference to an array and one which takes a reference to a pointer. If they really were the same then a reference to an array would be the same as a reference to a pointer.

void func1(int*& foo); // Parameter is a reference to a pointer

void func2(int (&foo)[4]); // Parameter is a reference to an array of length 4

You may have thought you knew what your code was doing but you didn''t. This is a more accurate representation of what you were trying to prove:


  void func1(int*& foo); // Parameter is a reference to a pointer


void func2(int (&foo)[4]); // Parameter is a reference to an array of length 4


void (*func[2])(int (&foo)[4]) = {&func1, &func2}; // Error on func1 because an array is not the same as a pointer

Share this post


Link to post
Share on other sites
quote:
Original post by smart_idiot
Well, my compiler can''t seem to tell the difference, but maybe it''s broken. Please enlighten it as to why it shouldn''t be compiling this program (besides that it was written by me):



          
#include <iostream>

#include <cstdlib>


// This does stuff to pointers.

void func1(int * foo) // A function using a pointer

{
++foo;
--foo;
*foo = 1;
foo[1] = 2;
*(foo+2) = 3;
(foo+1)[2] = 4;
}

// Hey, this looks exactly like func1!!!!

void func2(int foo[4]) // A function using an array

{
++foo;
--foo;
*foo = 1;
foo[1] = 2;
*(foo+2) = 3;
(foo+1)[2] = 4;
}

// Don''t the function''s signatures need to be the same to do this? Why is this working?

void (*func[2])(int foo[4]) = {&func1, &func2};
// This works too if you want to uncomment it and try it.

// void (*func[2])(int *foo) = {&func1, &func2};


// A nice unbiased way to show each type.

template <class T> void ShowElements(T var)
{
cout << var[0] << '' '' << var[1] << '' '' << var[2] << '' '' << var[3] << endl;
}

int main(void)
{
// A fitting way to display the title.

char array_text[7] = "Arrays";
char *pointer_text = "Pointers";
cout << array_text << " and " << pointer_text << endl;

// An array

int foo1[4];
// A pointer (using malloc to ignore constructors and show there is nothing special happening)

int *foo2(static_cast<int *>(malloc(sizeof(int)*4)));

func[0](foo1); // using an array as a pointer.

ShowElements(foo1);

func[1](foo1); // using an array as an array.

ShowElements(foo1);

func[0](foo2); // using a pointer as a pointer.

ShowElements(foo2);

func[1](foo2); // using a pointer as an array.

ShowElements(foo2);

free(foo2); // free the data we''re pointing to.


cin.get(); // Wait for the user to press a key.

}


[edited by - smart_idiot on November 20, 2002 11:58:01 PM]

I don''t see the problem. I seem to recall learning that that works fine in a compsci class a long time ago.

Share this post


Link to post
Share on other sites
quote:
Original post by ktuluorion
I don't see the problem. I seem to recall learning that that works fine in a compsci class a long time ago.


Because there isn't a problem, and the reason there isn't a problem is because the code doesn't do what smart_idiot WANTED it to do. If he did what he wanted it to do, then he would have found out that he was wrong. Refer to my previous post.

EDIT: After copying the code into my compiler (took this long cuz when i copy and paste it pastes it all as 1 line for some reason) , turns out he had some errors in his code OTHER than for what he was trying to prove so it didn't compile.

Moral of the story -- don't make a dragged out proof with mistakes in it and that isn't really a proof, especially when it can be disproven in just 3 lines

Or, if I really wanted to prove my point fast I could have done it in one:

cout << "Array: " << sizeof( char[1] ) << endl << "Pointer: " << sizeof( char* ) << endl;

If they were the same type, then their sizes would be the same.


[edited by - Matt Calabrese on November 20, 2002 12:26:14 AM]

Share this post


Link to post
Share on other sites
I don''t know if this will just add to the noise, but...

Pointers and arrays are not the same. If you have an array, you have a row of variables in memory, no pointer is involved. If you have a pointer, it''s like an address in memory.

The compiler can convert from an array to a pointer by using the address of the first element. The [] operator is defined for pointers to make it behave like it does for an array.

Arrays are always passed by reference into a function, meaning that the whole array isn''t passed in. If you modify the array inside the function, the caller''s array gets modified.

Hope this helps somehow!


Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions

Share this post


Link to post
Share on other sites
Hey, I figured out my problem. It wasnt actually in that routine, it was in the move_lemming() routine.

I have another important question. Why is it that either of the folloing work. whats the difference? And why can you not nest the routines?


struct stuff
{
int a;
char b;
};

// only needs one element
void funct1(struct stuff *elem)
{
printf("a=%d ",elem.a);
printf("b=%d\n",elem.b);
}

// needs multiple elements
void funct2(struct stuff *elem)
{
int i;
for (i=0; i< 5; i++) {
printf("a=%d ",elem->a);
printf("b=%d\n",elem[i]->b);
}
}

// combination of the two (dosent work)
void funct2(struct stuff *elem)
{
int i;
for (i=0; i< 5; i++) {
funct1(&test[i]);
}
}

int main()
{
struct stuff test[5];
funct1(&test[0]);
funct2(test);
funct3(test);
return 0;
}


This was just typed out of my head wo it *may* caontain an error. If so I appologize.



- Twisted Matrix

[edited by - TwistedMatrix on November 21, 2002 9:46:05 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by TwistedMatrix
I have another important question. Why is it that either of the folloing work.

They don''t. You have your member access operators the wrong way around. The code should look like this:


  
#include <stdio.h>


typedef struct STUFF // use typedef to enter stuff into the symbol table

{
int a;
char b;
} stuff;

void funct1(stuff *elem)
{
printf("a=%d ",elem->a);
printf("b=%d\n",elem->b);
}

void funct2(stuff *elem)
{
int i;
for (i=0; i< 5; i++)
{
printf("a=%d ",elem[i].a);
printf("b=%d\n",elem[i].b);
}
}

void funct3(stuff *elem)
{
int i;
for (i=0; i< 5; i++)
{
funct1(&elem[i]);
}
}

int main()
{
stuff test[5];
funct1(&test[0]);
funct2(test);
funct3(test);
}

quote:

whats the difference?

All functions have the same signature, and all expect a pointer to "stuff". The difference comes about in what assumptions you make about the the memory layout at "elem". For instance, in funct1(), you assume that you have a valid pointer to a "stuff" entity. In funct2(), you assume that you have a valid pointer to the beginning of an array of 5 "stuff" entities. In funct3(), you also assume that you have a valid pointer to 5 items, and then forward each of those pointers on to funct1(). The problems come when your assumptions breakdown, which is highly likely in a program of above-trivial complexity. If you want to pass a pointer to an array, you should at least pass an additional field stating how many elements the array passes. This is C bogosity at its best.
quote:

And why can you not nest the routines?

You mean why can''t you delegate from funct3() to funct1()? You can if you write your code correctly.

Share this post


Link to post
Share on other sites