Thread: Pointer/Dynamic Memory/function problem

  1. #1
    Registered User
    Join Date
    Nov 2004
    Posts
    49

    Pointer/Dynamic Memory/function problem

    Hello, Im tring to pass a pointer and assign its memory dynamically within the function. Can Someone tell me why my problem says i isnt being initalized when I pass it? And why it isnt dynamically allocating any memory. Thanks

    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    void f(int *p){
    	p=new int;
    }
    
    int main(){
    int *i;
    f(i);
    system("PAUSE");
    return 0;
    }
    Thanks for looking at my question.
    Take care.
    And Merry Post Christmas.

  2. #2
    Handy Andy andyhunter's Avatar
    Join Date
    Dec 2004
    Posts
    540
    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    void f(int *p){
    	p=new int;
    }
    
    int main(){
    	
    	int *i = NULL;
    	f(i);
    	
    	system("PAUSE");
    	return 0;
    
    }
    Happy Coding!

  3. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Feh, this explanation is harder in C++. :P Okay, unless you pass a reference explicitly, function parameters are passed by value. This includes pointers. When you pass i to f, a copy is made and assigned to p. Then memory is allocated and referenced by p, but when the function returns, p is destroyed because it goes out of scope. No changes were made to i because the pointer itself was copied.

    To fix this you can either pass a pointer to a pointer to simulate passing by reference:
    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    void f(int **p){
      *p=new int;
    }
    
    int main(){
      int *i;
      f(&i);
      system("PAUSE");
      return 0;
    }
    Or you can actually pass by reference because C++ supports that construct:
    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    void f(int*& p){
      p=new int;
    }
    
    int main(){
      int *i;
      f(i);
      system("PAUSE");
      return 0;
    }
    My best code is written with the delete key.

  4. #4
    Registered User
    Join Date
    Nov 2004
    Posts
    49
    Hello, I tested the code you gave me and assign I a Value, and I get the error: First-chance exception at 0x00411db4 in asdfregh4.exe: 0xC0000005: Access violation writing location 0x00000000.
    Unhandled exception at 0x00411db4 in asdfregh4.exe: 0xC0000005: Access violation writing location 0x00000000
    at runtime. Its like its not Dynamically Allocating the memory for I inside the function. Since its tring to write to location 0x00000000 which is the value of NULL I think.

    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    void f(int *p){
    	p=new int;
    }
    
    int main(){
    int *i=NULL;
    f(i);
    *i=5;
    system("PAUSE");
    return 0;
    }
    Thanks for the fast reply

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I tested the code you gave me and assign I a Value, and I get the error
    The code andyhunter gave you is wrong. It doesn't fix the problem you had. Watch:
    Code:
    int *i=NULL; // Null pointer
    f(i);        // Nothing happens to i!
    *i=5;        // Dereference a null pointer.
    Read my first post before trying any more broken solutions, please.
    My best code is written with the delete key.

  6. #6
    Registered User
    Join Date
    Nov 2004
    Posts
    49
    Oh thanks Prelude, What does *& mean? when you combine them like that? and I thought pointers arent passed by value cause I seen then do that with the swap functions for bubble sort I thought. But it seems it is. Thanks for letting me know. I dont really know why a double pointer lets it stimulate passed by reference and what *& means. It would be helpful if you can explain it to me. Thank you. For the fast reply you must of replyed right when I submited another reply to the Other Poster. Andy.

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >What does *& mean?
    It means a reference to a pointer, or a pointer reference. If you look up references in your book, you'll get a detailed account of how they work.

    >I seen then do that with the swap functions for bubble sort I thought
    There's a (subtle) difference between this:
    Code:
    void swap(int *a, int *b)
    {
      int save = *a;
      *a = *b;
      *b = save;
    }
    And this:
    Code:
    void alloc(int **p, int size)
    {
      *p = new int[size];
    }
    The first is assigning to the objects pointed to, so a pointer to the object is needed. The second is assigning to the pointer itself, so a pointer to the pointer is needed. The rule of thumb is that if you need to modify and object passed to a function, pass a pointer to it. I that object is an int, as in swap, pass an int*. If that object is a pointer, as in alloc, pass an int**.

    Of course, because C++ supports real references, there's little reason to simulate the effect with pointers.
    My best code is written with the delete key.

  8. #8
    Registered User
    Join Date
    Nov 2004
    Posts
    49
    Im still confused. But Thanks for all the information. I dont want to start asking too much questions and making people mad Lol I do that a lot. I find it hard to learn from books. they Never explain it in a way I can understand. Its always confusing. but Ill look around and see if I cant figure out the parts I dont understand. Like if Pointers are passed by value how does Passing a pointer to a pointer Cause the original to be affected? I was thinking about it. and I was thinking a pointer to a pointer causes the original pointer to point to the copy? If thats the case I understand Lol. and the second thing I didnt get was pointer reference. Its Just saying that the address of a pointer is needed? If thats the case I understand that too Well Thanks for all the help. Maybe You can read this if You feel like replying again and tell me if I got the right understanding. But Thanks For all the Help If you dont
    Take care Byebye

  9. #9
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    Don't worry about asking too many questions. It's not that that makes people mad. It's when you don't do your part to solve the problem. For example, if you come to us with homework and expect us to do parts you haven't even tried, or if you blatantly ignore our advice.

    It is a hard subject to explain, so I'll do my best, but I think you may understand it better than you think you do. Try going through the code Prelude gave you step by step and making a flow chart. Keep track of what is passed to each function, etc... You'll start to see how it works. YOu're right, it is an address of a pointer. Essentially, a pointer to a pointer. They use those a lot in Windows programming, and call it a handle.

  10. #10
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    The default method for passing arguments in C++ is by value. That is, a copy of the argument is made:
    Code:
    #include <iostream>
    
    using namespace std;
    
    int f(int a)
    {
      return ++a;
    }
    
    int main()
    {
      int i = 0;
    
      cout<< f(5) <<endl;
      cout<< f(i) <<endl;
      cout<< i <<endl;
    }
    The first key to understanding how this works is to realize that a is a separate variable from i, and it's local to f. The value of 5 is copied into a for the first call to f and the value of i (0) is copiled into a for the second call. The effect is equivalent to this:
    Code:
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      int i = 0;
      int a;
    
      a = 5;
      cout<< ++a <<endl;
      a = i;
      cout<< ++a <<endl;
      cout<< i <<endl;
    }
    Because any changes to a are completely separate from i, the value of i is never touched except to make the copy. Because of this, we can use literal values . If the original value could be modified then f(5) would be an error because you can't change the value of an integer literal. That's how passing by value works.

    In C, the situation arises where you need to pass an object by reference. This means passing the object in such a way that any changes to a would be reflected in i. Naturally, because you can't change the value of a literal, f(5) would no longer work under this scheme.

    However, because C doesn't support anything except passing by value, we need to simulate passing by reference by passing the address of i to f as a pointer.
    Code:
    #include <iostream>
    
    using namespace std;
    
    int f(int *a)
    {
      return ++(*a);
    }
    
    int main()
    {
      int i = 0;
    
      cout<< f(&i) <<endl;
      cout<< i <<endl;
    }
    This way, the original object (i) is accessable from within f. The address of i is still passed by value, but when the address is dereferenced, f has access to the actual value of i. Any changes to that value will be reflected by i when f returns. The equivalent behavior is:
    Code:
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      int i = 0;
    
      cout<< ++i <<endl;
      cout<< i <<endl;
    }
    This is how C can simulate passing by reference. The pointer is passed by value, but the address of the original object is still accessable. True passing by reference doesn't require this indirect sleight of hand because a true reference is a synonym for the original object. The two refer to the same thing, but are called different names.

    Now you should see how the rule of thumb came about: If you want to modify an object by passing it to a function, pass a pointer to the object.

    The nice thing about all of this is it's very regular. The rule applies for pointers too because pointers count as objects that hold addresses. The following does not work as expected:
    Code:
    #include <iostream>
    
    using namespace std;
    
    int i = 10;
    int j = 20;
    
    void f(int *a)
    {
      a = &j;
    }
    
    int main()
    {
      int *p = &i;
    
      cout<< *p <<endl;
      f(p);
      cout<< *p <<endl;
    }
    Because a is a pointer to i, the value of i can be changed through a, but the address that p points to cannot be changed because a is a copy of the address. To re-assign p to j, you need to pass a pointer to the pointer to the function:
    Code:
    #include <iostream>
    
    using namespace std;
    
    int i = 10;
    int j = 20;
    
    void f(int **a)
    {
      *a = &j;
    }
    
    int main()
    {
      int *p = &i;
    
      cout<< *p <<endl;
      f(&p);
      cout<< *p <<endl;
    }
    The same rule applies for a pointer to a pointer. If you want to dynamically allocate a two dimensional array of int (int **) from another function, you need to pass a pointer to int ** (int ***):
    Code:
    #include <iostream>
    
    using namespace std;
    
    void alloc2d(int ***mat)
    {
      *mat = new int*[5];
      for (int i = 0; i < 5; i++)
        (*mat)[i] = new int[5];
    }
    
    int main()
    {
      int **p;
    
      alloc2d(&p);
    }
    The "obvious" solution:
    Code:
    #include <iostream>
    
    using namespace std;
    
    void alloc2d(int **mat)
    {
      mat = new int*[5];
      for (int i = 0; i < 5; i++)
        mat[i] = new int[5];
    }
    
    int main()
    {
      int **p;
    
      alloc2d(p);
    }
    Wouldn't work for the same reason that a pointer passed as a pointer can't be re-assigned. To modify the original, you need a pointer to it. Fortunately, you'll be hard pressed to ever use more than single indirection in C++. In C you should be surprised to use more than triple indirection (though I have used more than that before, but only once).

    Stepping away from the C way of doing things, C++ supports true references. To pass an integer by reference and have the changes reflected in main, you simply would do this:
    Code:
    #include <iostream>
    
    using namespace std;
    
    int f(int& a)
    {
      return ++a;
    }
    
    int main()
    {
      int i = 5;
    
      cout<< f(i) <<endl;
      cout<< i <<endl;
    }
    It's easier to get right because you don't have to play with multiple levels of indirection, and it's intuitive. To pass a pointer by reference so that you can allocate memory to it, you tack a & on the end of the type in your parameter list:
    Code:
    #include <iostream>
    
    using namespace std;
    
    void alloc(int*& a)
    {
      a = new int;
    }
    
    int main()
    {
      int *i;
    
      alloc(i);
      *i = 0;
    }
    Once again, the syntax and behavior are very regular. To allocate a two dimensional array, you take the "obvious" solution and pass a reference:
    Code:
    #include <iostream>
    
    using namespace std;
    
    void alloc2d(int**& mat)
    {
      mat = new int*[5];
      for (int i = 0; i < 5; i++)
        mat[i] = new int[5];
    }
    
    int main()
    {
      int **p;
    
      alloc2d(p);
    }
    Now it's obvious and correct.

    When using C++, you should try using references first, and then pointers if references don't work out. The pointer solution is a bit of a hack to work around the default argument passing scheme in C. Because C++ supports other schemes, the hack isn't always appropriate anymore.
    My best code is written with the delete key.

  11. #11
    Registered User
    Join Date
    Nov 2004
    Posts
    49
    I am Totally Confused. I read your post like a million times and I just cant grasp it.
    What I get which may or may not be wrong is:
    1.Functions by default pass by value.
    2. Passing by Value is Taking a Copy of the Value in one Variable and Storing it in Another Variable.
    3. A Pointer is passed by Value by Making a Copy of the Address it holds and storing it in another Pointer.
    4. When you Deference the Copy of the Address. The Value At that Address. Copy or not is Pointed to.
    Code:
    #include <iostream>
    
    using namespace std;
    
    int i = 10;
    int j = 20;
    
    void f(int *a)
    {
      a = &j;
    }
    
    int main()
    {
      int *p = &i;// Copy of address i is stored in p
    
      cout<< *p <<endl;// dereferences copy of address i to get value stored at copy of address
      f(p);// copy of address of i in p is stored in pointer a. 
    // then a is assigned copy of address j. 
    // a goes out of scope and dissapears.
      cout<< *p <<endl; // p still points at copy of of address i.
    }
    whats in direction?
    *& still confuses me.
    blows air.
    Do you need the & after the * cause the address of the pointer isnt passed. only the address stored in the pointer?
    Well I tried hehe.
    How did I do? Lol this is difficult for me to grasp. I dont go to school for it. I usually just try to understand it from web pages and chat rooms as a hobby. I want to make a graphical chat game and 4 years of tring to learn programming isnt getting me far LOl. Still a beginner of dos world lOL. sad sight
    But then I dont really study hard I just read and try to remember.
    I dont think Im a programmar but I really want to make a game chat thing for my friend and me
    Well byebye Thanks
    Tell me how I did. Which parts I didnt get right.

  12. #12
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >1.Functions by default pass by value.
    >2. Passing by Value is Taking a Copy of the Value in one Variable and Storing it in Another Variable.
    >3. A Pointer is passed by Value by Making a Copy of the Address it holds and storing it in another Pointer.
    >4. When you Deference the Copy of the Address. The Value At that Address. Copy or not is Pointed to.
    Right on all counts.

    >*& still confuses me.
    I can understand that. & is used in several wildly different contexts. Read the declaration from right to left:
    Code:
    int*& a; // A is a reference to a pointer to int
    My best code is written with the delete key.

  13. #13
    Registered User
    Join Date
    Nov 2004
    Posts
    49
    Well Thanks. I Think I understand More then I did before at least. Well Enough for me to Use it in code perhaps
    Thanks for all the help.

  14. #14
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    Awesome new sig, Prelude!

  15. #15
    Registered User
    Join Date
    Apr 2004
    Posts
    29
    Quote Originally Posted by Prelude
    >What does *& mean?
    It means a reference to a pointer, or a pointer reference. If you look up references in your book, you'll get a detailed account of how they work.

    What is your favorite book as far as explaining all of this pointer/reference arithmetic?

    All I know is:
    using pointers to declare an address pointer to have a dynamic array, using malloc (and also new)

    and

    pass by reference in its simplest form :
    Code:
    #include <iostream.h>
    char ImplementChar(char *c);
    char PassingToAThirdFunction(char *C);
    
    void main(void)
    {
    char c;
    c='*';
    cout << ImplementChar(&c) << endl;
    
    }
    char ImplementChar(char *c)
    {
    char d=*c;
    cout << PassingToAThirdFunction(c) << endl;
    return d;
    }
    char PassingToAThirdFunction(char *C)
    {
    char e=*C;
    return e;
    }
    Quote Originally Posted by Artist_of_dream
    problem says i isnt being initalized when I pass it? And why it isnt dynamically allocating any memory.
    page 97 in Stroustropp: [p]To ensure that a reference is a name for something (that is, bound to an object), we must initialize the reference. For example:
    Code:
    int i=1;
    int& r1=i;   // This initializes r
    I just tried your code in my VC5 compiler and didn't get any errors.

    I put in a cout
    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    void f(int *p){
    	p=new int;
    	cout << p << endl;
    }
    
    int main(){
    int *i;
    f(i);
    system("PAUSE");
    return 0;
    }
    and got the output

    00461280
    Press any key to continue . . .


    As for Andy's
    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    void f(int *p){
    	p=new int;
    	cout << p << endl;
    }
    
    int main(){
    	
    	int *i = NULL;
    	f(i);
    	
    	system("PAUSE");
    	return 0;
    
    }
    I'm not getting any output.

    Stroustropp doesn't mention anything about passing references [i]explicitly[/], or else it just isn't in the index. What is in the index is explicit constructor.

    [p]By default, a single argument constructor also defines an implicit constructor.

    From this I derive that the space for the reference will not be worked out for you that you must define it. Okay, Prelude. I talso talks about copy constructors like you mentioned a copy is made.

    [p] In particular, where a copy constructor is in principle needed, an explicit constructor will not be implicitly invoked.

    I'm just trying to see where I can take your discussion and use it myself somewhere because I am in a long spell of not programming anything. I don't see why *& is used. It looks sort of strange to me to. Must be something about your newer compilers.

    Anyway, what was the book?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help understanding a problem
    By dnguyen1022 in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2009, 04:21 PM
  2. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  3. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  4. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  5. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM