Thread: Let's talk practically about pointers

  1. #1
    Registered User
    Join Date
    Apr 2011
    Posts
    17

    Let's talk practically about pointers

    When I assign a pointer, like this
    Code:
    int *p;
    and when I want to treat it as an array by doing something like this

    Code:
    for(i=0;i<10;i++)
    scanf("%d",&p[i];
    how the computer knows that, for example, the p+4 adress it's not in use?
    I mean how the heck does this work?

    P.S.I've heard that you can somehow allocate memory in order to use it using malloc(), but I've seen that the above code is working without using malloc.

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Cevris View Post
    I've seen that the above code is working without using malloc.
    Just because code seems to work does not make it valid. For example, the C standard often refers to undefined behavior. Invalid code of that sort is not required to do anything, but it could do...anything (hence, undefined). Quite often it will do what you thought it would, but since you have no guarrantees it will do that again next time, you should never never never rely on code whose behaviour is undefinable. Code which exploits undefined behavior, accidentally or otherwise, is very bad code.

    Quote Originally Posted by Cevris View Post
    how the computer knows that, for example, the p+4 adress it's not in use?
    It doesn't, and it might be. If it is, and it is memory used by your program, various funny things can happen. If it is memory that does not belong to your program, this is an access violation and your operating system will not allow it to happen. Your program will "segementation fault".

    Quote Originally Posted by Cevris View Post
    P.S.I've heard that you can somehow allocate memory in order to use it using malloc(),
    Yes. Then the memory will be reserved properly, meaning the computer knows it is not being used for anything else.
    Last edited by MK27; 04-23-2011 at 05:40 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Apr 2011
    Posts
    17
    Thank you for your immediate and informative reply.
    So, by using malloc() to allocate 10*sizeof(int) bytes, the pointers' addresses may not be consecutive.Is that right?
    For example:
    p=100
    p+1=104
    p+2=112
    because 108 is already in use?

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Cevris View Post
    Thank you for your immediate and informative reply.
    So, by using malloc() to allocate 10*sizeof(int) bytes, the pointers' addresses may not be consecutive.Is that right?
    For example:
    p=100
    p+1=104
    p+2=112
    because 108 is already in use?
    You're welcome

    Fortunately, the C standard does require some things from compilers besides undefined behavior. One of them is that malloc'd memory be contiguous, so in fact the addresses will be consecutive:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, const char *argv[]) {
    	int *p = malloc(sizeof(int)*10), i;
    
    	if (!p) {
    		puts("Out of memory!");
    		return -1;
    	}
    
    	for (i = 0; i < 10; i++) {
    		printf("%p\n", &p[i]);
    	}
    
    	free(p);
    
    	return 0;
    }
    &p[i] is the address of pointer i in the array. Each memory address represents a single byte, and since this is an array of integers, each element of the array is four bytes, so the address of each element is 4 bytes apart. That is still contiguous/consecutive, tho; you can write 10 integers into the location at p and they will fill the array. You can also use arithmetic on a pointer (p+1, p+2) and the compiler compensates (ie, p+1 == p[1]), the units are the size of the datatype, not bytes.

    It's a good practice to check the return value of malloc to make sure it is not NULL, and you should always use free() when you are done with the memory.

    ps. the C standard is not the best practical reference for beginners, and the online version is actually a "draft"; the "real" one is mail order. But it does exist!
    Last edited by MK27; 04-23-2011 at 06:11 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    If p[108] was already allocated for something else, then malloc() would not have given you that block of addresses. Malloc and calloc will either give you ALL the memory you request, or it will fail, and give you no memory at all - there is nothing in-between" "Do or do not, there is no try."

    A single dimension (a row) of an array, will be allocated as consecutive memory. In a two dimension array (with multiple rows), if every row is allocated separately, then the compiler may give each row, a row's worth of memory, which is consecutive with the next row's memory. However, that is not required. Each row WILL have consecutively numbered addresses, but one row's memory may NOT be right next to the next row's memory.

    In other words, a separate call to malloc, MAY get a completely non-consecutive block of memory, even though the calls are done one right after the other.
    Last edited by Adak; 04-23-2011 at 09:46 AM.

  6. #6
    Registered User
    Join Date
    Apr 2011
    Posts
    17
    Thanks to both of you.
    I have another problem that needs solution.

    Code:
    int *returnPtr(int a,int b,int x[])
    {
      x[0]=a;
      x[1]=b;
      return x;
    
    
    }
    
    int *corner(char array1[],int x[])
    {   int i;
        for(i=0;i<5;i++)
          if(array1[i]=='s')
            return returnPtr(1,1,x);
    
    
    }
    These are two functions that return a pointer, and I use the first one INSIDE the other one. But why my programm crashes?

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    A pointer to an int is not the same thing as a pointer to an array of int. Once you get outside the strict definition of what the pointer is, what you wind up with is a bucketful of undefined behavior - something might work, used this way, but won't work used that way, and crashes when used this other way - works in this program, but same code won't work in that program, works on this computer, but not on that computer with the same operating system and compiler, etc.

    With your first step outside the standard for C, you're knee deep in "uffda", and there's no telling whether you'll sink further or swim.

  8. #8
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Adak View Post
    With your first step outside the standard for C, you're knee deep in "uffda", and there's no telling whether you'll sink further or swim.
    As Laserlight once pointed out : Undefined behavior means it will work perfectly until you are showing off to your boss.

  9. #9
    Registered User
    Join Date
    Apr 2011
    Posts
    23
    On the topic of pointers, I'm going through a well written tutorial book, and I just finished the chapter on pointers, but I left only half satisfied with what I learned. Everything I've learned up to this point I completely understood, just not pointers.

    Can someone point me towards some good pointer tutorials, as I understand I really need to grasp them fully before I continue.

  10. #10
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Pointers are just like any other variable. All variables hold a value. Everything in C is done by value. If you pass a number to a function, it doesn't pass a variable to you, it passes the value the variable holds. Everything is a value.

    The value pointers hold represent a memory address to a variable of the same type:
    Code:
    char c; /* holds a 'char' value */
    char *p; /* holds a 'char *' value */
    Pointers are really just numbers. The number represents a memory address. It's like if I asked you what number your favorite sports team member wears. "Oh he's 23.", Ok, so when you see 23 on the field/floor you know that it really is the guy whose name you like out there. His "pointer" is 23. Make sense?

    When you dereference a pointer you are asking the pointer to give you the value that the spot in memory whose address your pointer holds contains. Confused? Don't be:
    Code:
    char c = 'a'; /* put the value that 'a' represents in c */
    char *p = &c; /* put the value of the address in memory that c has into p */
    
    printf( "%c", *p ); /* dereference p to get the value that memory address holds */
    Dereferencing just says "go to the spot in memory that your value is, and get me the value that is there".

    There is also a tutorial section if you go up and click on the FAQ that should have a pointer tutorial or two.


    Quzah.
    Hope is the first step on the road to disappointment.

  11. #11
    -bleh-
    Join Date
    Aug 2010
    Location
    somewhere in this universe
    Posts
    463
    Quote Originally Posted by ModeSix View Post
    On the topic of pointers, I'm going through a well written tutorial book, and I just finished the chapter on pointers, but I left only half satisfied with what I learned. Everything I've learned up to this point I completely understood, just not pointers.

    Can someone point me towards some good pointer tutorials, as I understand I really need to grasp them fully before I continue.
    Instead of going to a different source, why not rereading that section on pointer again :-D ? Pointer is pretty basic, so a lot of example at this point is going to be almost identical anyway.
    Last edited by nimitzhunter; 04-23-2011 at 04:01 PM.
    "All that we see or seem
    Is but a dream within a dream." - Poe

  12. #12
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by nimitzhunter View Post
    Instead of going to a different source, why not rereading that section on pointer again :-D ? Pointer is pretty basic, so a lot of example at this point is going to be almost identical anyway.
    The way I explain pointers may be easy for one person to understand, but difficult for someone else. Having multiple points of reference is seldom a bad thing.

    Q. "How do I get to Bob's house?"
    A1. "It's on 3rd and Main."
    A2. "Go down to the corner, turn right, go five blocks. Number 308."
    A3. "Cut through that field, go down the next road until you see a pink house. Just past that, on the left. You can't miss it."

    Quzah.
    Hope is the first step on the road to disappointment.

  13. #13
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by ModeSix View Post
    On the topic of pointers, I'm going through a well written tutorial book, and I just finished the chapter on pointers, but I left only half satisfied with what I learned. Everything I've learned up to this point I completely understood, just not pointers.

    Can someone point me towards some good pointer tutorials, as I understand I really need to grasp them fully before I continue.

    Pointers are actually very simple devices... They work like post office boxes... you know where the box is, but you don't know what's inside...
    Code:
    int *pobox;  // the intention to rent.
    int x;          //  empty pobox.
    
    pobox = &x;  // renting the box
    
    x = 42;    // postmaster putting something in the pobox
    
    prinf("%X",(unsigned int) pobox);  // the pobox number.
    
    printf("%d", *pobox);  // looking inside 
    
    *pobox = 127;   // putting stuff in the box
    Note that C tries to use pointers in the same way they're created... int *pobox (to create a pointer) and *pobox (to access the value at the pionter) are good examples... However, these are two different things, they do different things and they're what cause the most confusion. (IMO it was a mistake to do it this way, but that is how it is...)

    & means "Address of" ... or "Pointer to"... and gives you the location of a value.

    int *pobox ... declares pobox as a pointer... it holds the address of something

    *pobox ... "dereferences" pobox... it looks past the pointer to see the content at that address.


    Beyond that it's mostly just combinations of effects. The real trick is to not complicate the thing...

    Cprogramming.com Tutorial: Pointers

  14. #14
    Registered User
    Join Date
    Apr 2011
    Posts
    17
    Quote Originally Posted by Adak View Post
    A pointer to an int is not the same thing as a pointer to an array of int. Once you get outside the strict definition of what the pointer is, what you wind up with is a bucketful of undefined behavior - something might work, used this way, but won't work used that way, and crashes when used this other way - works in this program, but same code won't work in that program, works on this computer, but not on that computer with the same operating system and compiler, etc.

    With your first step outside the standard for C, you're knee deep in "uffda", and there's no telling whether you'll sink further or swim.
    So what are the changes that I have to do in order to receive an array of two things by calling the second function?

  15. #15
    Registered User
    Join Date
    Apr 2011
    Posts
    23
    Thanks guys. What each of you have said makes sense to me in different ways. I may just be overthinking pointers. I am going to go over the linked tutorial to see if that helps me with the concepts I am getting confused. Great info from everyone. Thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Do I talk too much?
    By GoodStuff in forum A Brief History of Cprogramming.com
    Replies: 11
    Last Post: 05-20-2003, 10:45 PM
  2. Who wants to talk on AIM?
    By Death Wish in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 07-05-2002, 06:29 AM