Thread: pointers

  1. #1
    Registered User
    Join Date
    Mar 2004
    Posts
    494

    pointers

    why are pointers so difficult to understand? Im really having a hard time thinking the "pointers way" any ideas of how to approach this issue?
    When no one helps you out. Call google();

  2. #2
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    New York
    Posts
    1,905
    http://cboard.cprogramming.com/showthread.php?t=60080

    Just do a board search on pointers, you'll find tons and tons of posts of really good explanations by a lot of the members here. There was a pointers video I saw a while ago....a claymation thing...anyone remember what it was called/where it's at?


    -edit-
    Ah hah, found it:
    http://cslibrary.stanford.edu/104/

    That should help a bit.

  3. #3
    Registered User Sake's Avatar
    Join Date
    Jan 2005
    Posts
    89
    >>why are pointers so difficult to understand?
    Um...42?

    But seriously, pointers are really easy to grasp; they're just references to memory addresses. I think that everyone just makes them hard because they sound low level and complicated, or because pointers are a common source of errors.

    >>any ideas of how to approach this issue?
    Just keep hacking away at it. Eventually, someone will explain it with their eyebrows twitching in the right sequence during the right phase of the moon and everything will click.
    Kampai!

  4. #4
    People Love Me
    Join Date
    Jan 2003
    Posts
    412
    Pointers are arguably the most difficult concept to understand in C++ because of 2 main reasons:

    1.) The syntax is often hard to understand
    Code:
    int (*p)(int a, int*) = &func;
    2.) They have a WIDE range of applications from class objects to linked lists.

  5. #5
    Registered User
    Join Date
    Aug 2004
    Posts
    66
    I believe pointers are not so hard to use, however, they seem complicated because the apparently weird syntaxis, however, you could create a small program using various of the different ways poiters work, in an array and the different outputs they can have, this way you could use it as a guide any time you are confused about what to use when writing a huge code, after a while you'll be able to write code without watching the small program

  6. #6

    Post

    Hello,

    Pointers are facile, yet confusing. Thinking in the programming world isn’t easy, and comprehending everything read, intricate. Even though pointers are for the experienced, as they say, I’m here to guide programmers consisting of all levels to greaten their understanding of pointers, and why they are pertinent to your everyday programming.

    Pointer Fundamentals
    Let me start off by stating, a pointer is a variable that contains the address of another variable. Pointers and arrays are closely related, though pointers are sometimes the only way to express a computation. Some also say pointers lead to more compact and efficient code. If you view the following example [1.1], it may be confusing and you’ll see the incompleteness of it:
    Code:
    int main() {
        /* local variables */
        char c;
        char ch[2];
        char *pch;
    
        c = 'a';
        ch[0] = 'a'
        *pch = ch[0];
    
        /* end program */
        return 0;
    }
    Example 1.1: An incomplete look at pointers

    Pointers and addresses require allocation to store its data. Unlike the char and char[] data types, which use locally stacked memory, pointers pass though existing memory stacks.

    The unary operator “&” gives the memory address of an existing object. This assigns the address of one variable and “points to” another. Remember, pointers use existing memory, so we can either send a freed block of memory to a pointer, or assign it another variables’ address. Let me lead this with an example:
    Code:
    #include <stdio.h>
    
    int main() {
        /* local variables */
        int n = 3;
        int *ptr;
    
        /* point ptr to n */
        ptr = &n;
    
        /* memory address */
        printf("%p\n", (void *)ptr);
    
        /* data */
        printf("%d\n", *ptr);
    
        /* end program */
        return 0;
    }
    Example 1.2: A closer look into pointers and addresses

    If you have tried to compile this short example, you may see that it did not result in a crash. This is because we sent our memory address of the variable n to ptr. Here, ptr does not receive its own block of memory, yet it points to an existing variable, n. The same implementation applies in other situations, such as arrays:
    Code:
    int main() {
        /* local variables */
        int n[5];
        int *ptr;
    
        /* point ptr to n */
        ptr = &n[0];
        *ptr = 3;
    
        /* end program */
        return 0;
    }
    Example 1.3: Sending a memory address to a pointer

    Or, you might want to consistently move the pointers position to correspond with all 5 slots of the array {0, 1, 2, 3, 4}. This is called pointer arithmetic, and is very possible to do with ease. An example:
    Code:
    #include <stdio.h>
    
    int main() {
        /* local variables */
        int n[5] = {10,20,30,40,50};
        int *ptr;
    
        /* points to n[0]*/
        ptr = &n[0];
        printf("ptr now points to n[%d] whose value is %d\n", (int)(ptr - n), *ptr);
    
        /* points to n[1] */
        ptr++;
        printf("ptr now points to n[%d] whose value is %d\n", (int)(ptr - n), *ptr);
    
        /* this expression references n[2], but ptr remains the same */
        *(ptr+1);
        printf("ptr now points to n[%d] whose value is %d\n", (int)(ptr - n), *ptr);
    
        /* this decrements the value of the content of the location pointed by ptr */
        (*ptr)--;
        printf("ptr now points to n[%d] whose value is %d\n", (int)(ptr - n), *ptr);
    
        /* this increments the value of the content of the location pointed by ptr */
        ++*ptr;
        printf("ptr now points to n[%d] whose value is %d\n", (int)(ptr - n), *ptr);
    
        /* end program */
        return 0;
    }
    Example 1.4: Pointer arithmetic

    Pointer arithmetic may seem confusing, but it’s just like adding and subtracting. *ptr is the data of your pointer, while ptr is the location. The “++” is an operator that remedies the choice of “+= 1”, or in other terms, “increments the variable by 1”. To reference extended positions, the recommended arithmetic would be “*(ptr+x)” as x represents your incrementing position.

    Pointers are used in real day-to-day programs. For example, take the following question and convert it to C syntax accordingly:

    There are 3 people in room A, and 5 people in room B. If the people in each room switched rooms, how many people would be in room A and room B?

    Note: This seems extremely easy and would best serve if we used pointers in this situation. Let me explain. As logically explained above, we are to swap the people within Room A and Room B, and produce an answer. With our current knowledge of pointers, this can be done feasibly:
    Code:
    #include <stdio.h>
    
    void reverse(int *x, int *y);
    
    int main() {
        /* Represent room A and B */
        int A = 3, B = 5;
    
        /* send local variable addresses to function */
        reverse(&A, &B);
    
        /* print result */
        printf("Room A: %d\nRoom B: %d\n", A, B);
    
        /* end program */
        return 0;
    }
    
    void reverse(int *x, int *y) {
        /* temporary variable */
        int temp;
    
        /* hold temporary variable that wont change */
        temp = *x;
    
        /* set x to y */
        *x = *y;
    
        /* set y to what x was temporarily before */
        *y = temp;
    }
    Code 1.1: Reversing two numbers using pointer knowledge

    As stated in code, void reverse(int *x, int *y) did a simple calculation and reversed A and B. The reason we used a temporary variable was to store the data of x. If we had set “*x = *y” and “*y = *x” it would have caused a problem no matter which we would call first. To break it down, we would literally state “1 [x] = 2 [y]”, then “2 [y] = 2 [x]”. Keeping the previous state of *x was very crucial.

    Simply, We sent our function void reverse(int *x, int *y) the memory addresses of A and B. That’s where the unary operator comes in handy. Send the addresses of A and B to *x and *y, swap out the two and we’re done. If we had not worked with pointers, we would have to create another set of variables, say, A0 and B0, then send A to B0, and B to A0 yet implementing a swap with unnecessary code congestion.

    » Pointers in the char data type realm
    We just discussed pointers from the integer perspective, and one-dimensional figures. As we may know, there are multiple dimensions in a programming environment. In which we must take the appropriate steps to accommodate all surrounding aspects.

    The character array realm is different from the integer, as we must deal with multiple instances in one variable. They both dwindle down to the fact of digits, as the ASCII Table defines. Standard ASCII, and signed char’s represent 0 thru 127. With those numbers, the char reads them as letters, or in the ASCII environment. To explain a character array is in the same mindset:
    Code:
    int main() {
        /* local variables */
        int iCh;
        char ch;      /* signed */
        char ca[3];
    
        ch = 'a';     /* or 97 in ASCII */
        iCh = 98;     /* 98 is 'b' in ASCII */
        ca[0] = ch;   /* first index is 'a' */
        ca[1] = (char)iCh;   /* second index is 'b' [type cast the integer to char] */
        ca[2] = 'c';  /* third index is 'c' */
        ca[3] = '\0'; /* fourth ends here */
    
        /* end program */
        return 0;
    }
    Example 2.1: Character arrays in the integer environment

    The example shown is still within the “one-dimensional” environment. Character pointers also need a valid memory address to write to, like integers.

    Pointing a “character pointer” to a valid memory address isn’t as simple as seen before from the integer perspective. The following can be utilized, but is not recommended by most:
    Code:
    int main() {
        /* local variables */
        char text[6] = "Hello";
        char *ptr;
    
        /* not recommended */
        ptr = &text[0];
    
        /* end program */
        return 0;
    }
    Example 2.2: Pointing a pointer to, though not recommended

    As seen in this example, we initialized text to “Hello” which is 5 letters long resulting {‘H’, ‘e’, ‘l’, ‘l’ ‘o’, ‘\0’} 4 indices in the array system. Arrays always start at 0 and ‘\0’ is at the fifth location, [5].

    Next, is a more efficient way of receiving the memory address of a local variable. Even though it’s not recommended, it ensures linkage between the two variables:
    Code:
    void pointTo(char **src, char *dst);
    
    int main() {
        /* local variables */
        char text[3];
        char *ptr;
    
        /* point our pointer to our local variable */
        pointTo(&ptr, text);
    
        /* modify pointer data; affects local data due to pointer linkage */
        ptr[0] = 'A';
        ptr[1] = '\0';
    
        /* end program */
        return 0;
    }
    
    void pointTo(char **src, char *dst) {
        *src = dst;
    }
    Example 2.3: Linking a pointer to a local variable

    Not exactly a two-dimensional pointer. We just need to send a pointer’s address to a function resulting in the pointer’s “*” pointer “*”. In void pointTo(char **, char *); we point dst to the pointed pointer *src.

    To ensure a pointer has a memory block without risking the chance of our local variable failing, we would take an opposite approach and allocate memory right from your machine's core.

    » Memory allocation in C
    We previously learned how to link memory addresses to pointers, but now its time to move to a more stable and serious approach: Handling memory from the core.

    This is no time at all to write a function or algorithm to space partition memory and issue it accordingly. That’s why the ANSI standard incorporated a function within the Standard C Library called void *malloc(unsigned int);. This function works in a unique way, sending the pointer memory of an empty/unused memory blcok of your requested size. This function will fail if there is insufficient memory from the system. Here is an example:
    Code:
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    
    int main() {
        /* local variables */
        char *ptr;
    
        /* dynamically allocate memory */
        ptr = malloc(6);
        /* if allocation failed */
        if (!ptr)
            /* end application */
            return 0;
    
        /* copy data to pointer */
        strcpy(ptr, "Hello");
    
        /* print data */
        printf("%s\n", ptr);
    
        /* free data */
        free(ptr);
    
        /* end program */
        return 0;
    }
    Code 2.1: Allocating memory the right way

    Let’s ask for 6 bytes of memory to work with. If it can’t be found, end the program before a fatal crash occurs. Else, copy 5 letters to our 5 bytes leaving enough room for the NULL terminator ‘\0’. Once we are finished with out memory, we will free it. void free(void *); deallocates any dynamically allocated memory if previously allocated by a call to malloc(). This function is also provided by the standard library stdlib.h. char *strcpy(char *, const char *); is also within the included function(s) written in the standard header files, though this one is declared in string.h. This function, strcpy(), isn’t hard to re-implement. In fact, it just takes a few pointer skills:
    Code:
    char* strcpy(char *dest, const char *src) {
        char *s = dest;
    
        while (*src)
            *s++ = *src++;
        *s = 0;
    
        return dest;
    }
    Example 2.4: Copy one string to another
    Note: Remember, if you have <string.h> included, don’t add these functions to our code example. Library’s and functions will conflict, yet leading to errors.

    I won’t get into great detail on this function. The main functioning of this is, that we increment *src and *s while copying the data from *src to *s while *src still exists. Once done, set the null terminator, and return dest as *s points to it.

    » Multi-dimensional pointers
    As tricky as it may sound, multi-dimensional pointers are just as easy as one-dimensional pointers, so don’t give up!

    As opposed to pointers, arrays can also work in a multi-dimensional realm. For example:

    Lets take:
    Code:
    int myValue[2][3];
    Or for a more detailed look would be as the following:
    Code:
    Rows/Columns    Column 0         Column 1         Column 2
    Row 0           myValue[0][0]    myValue[0][1]    myValue[0][2]
    Row 1           myValue[1][0]    myValue[1][1]    myValue[1][2]
    That should make a lot of sense. If its to confusing, lets break it down:
    Code:
    int myValue[2][3] = { {5, -3, 0}, {10, 17, -25} };
    Code:
    Rows/Columns    Column 0    Column 1    Column 2
    Row 0           5           -3          0
    Row 1           10          17          -25
    This is beginning to look simpler by the minute. As we previously discussed, the character environment is somewhat different, but not always.

    Look at this example:
    Code:
    char letters[2][3] = { {'A'}, {'D', 'E'} };
    Code:
    Rows/Columns    Column 0    Column 1    Column 2
    Row 0           A           ‘\0’        ‘\0’
    Row 1           D           E          ‘\0’
    As seen above, two-dimensional arrays consist of “row” and “column”, as one-dimensional consists of “column”. Allocating memory to two-dimensional arrays can be tricky, so here are some good steps to remember:
    • Know your Row count first.
    • Know your Column count next.
    • Know your Column length.

    In this order, everything should come together smoothly. Lets take a look at an example:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    int main() {
        /* Local variables */
        int i, j;
        int rows = 6;
        char word[6][12] = {"Hello", "Good-Bye!", "Greetings",
                            "Pointers", "Arrays", "Programming"};
        char **ptr = NULL;
    
        /* Allocate room for rows */
        ptr = malloc(rows * sizeof *ptr);
    
        /* If allocation succeeded */
        if (ptr) {
            /* Loop through all columns */
            for (i = 0; i < rows; i++) {
                /* Allocate */
                ptr[i] = malloc(strlen(word[i]) + 1);
                /* If allocation succeeded */
                if (ptr[i])
                    /* Copy data to our pointers memory */
                    strcpy(ptr[i], word[i]);
            }
        }else {
            /* Allocation failed */
            return 0;
        }
    
        /* Print data */
        for (i = 0; i < rows; i++)
            printf("%s\n", ptr[i]);
    
        /* Free memory */
        for (j = 0; j < rows; j++)
            free(ptr[j]);
        free(ptr);
    
        /* End program */
        return 0;
    }
    Code 3.1: Using two-dimensional arrays

    The comments in the code help guide you through each step. The sizeof function comes in handy during this process. We need to multiply our allocation size with the size of our variable to assure we have enough space to allocate anything else. Without that, our program may terminate unexpectedly.

    Pointers may seem difficult at this point, but its making perfect sense. There comes a time when it begins to advance. I do hope this short tutorial has been helpful to you. Before I’m done, I’d like to explore three-dimensional pointers. This too has a background of difficulty, but in the right perspective it too can be made easy.

    » Three-Dimensional Pointers
    This is an easy subject I like to think. It’s as easy as 1, 2, 3. Think of this as a Book. A book is three dimensions; depth, row, and column.

    For example:
    Code:
    int Book[2][3][4];
    Code:
    Book – Page[0]:
    Rows/Columns    Column 0         Column 1         Column 2         Column 3
    Row 0           Book[0][0][0]    Book[0][0][1]    Book[0][0][2]    Book[0][0][3]
    Row 1           Book[0][1][0]    Book[0][1][1]    Book[0][1][2]    Book[0][1][3]
    Row 2           Book[0][2][0]    Book[0][2][1]    Book[0][2][2]    Book[0][2][3]
    
    
    Book – Page[1]:
    Rows/Columns    Column 0         Column 1         Column 2         Column 3
    Row 0           Book[1][0][0]    Book[1][0][1]    Book[1][0][2]    Book[1][0][3]
    Row 1           Book[1][1][0]    Book[1][1][1]    Book[1][1][2]    Book[1][1][3]
    Row 2           Book[1][2][0]    Book[1][2][1]    Book[1][2][2]    Book[1][2][3]
    Or, in initialization:
    Code:
    int Book[2][3][4]; = { 
    { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} }    /* Page 0 */
    { {12, 13, 14, 15}, {16, 17, 18, 19}, {20, 21, 22, 23} }    /* Page 1 */
    };
    Code:
    Book – Page[0]:
    Rows/Columns    Column 0     Column 1     Column 2     Column 3
    Row 0           0            1            2            3
    Row 1           4            5            6            7
    Row 2           8            9            10           11
    
    Book – Page[1]:
    Rows/Columns    Column 0     Column 1     Column 2     Column 3
    Row 0           12           13           14           15
    Row 1           16           17           18           19
    Row 2           20           21           22           23
    I hope this is all coming together. Of course taking special measures for memory allocation is always needed. I’ll show an example:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    int main() {
        int i, j, k, p;          /* For loops */
        int pNum;                /* Page number */
        int pGraphs;             /* Paragraphs per page */
        char paragraph[4][256];  /* Our paragraphs */
        char ***Book = NULL;     /* Our book */
    
        /* Copy data to string */
        strcpy(paragraph[0], "Pointers are awesome!");
        strcpy(paragraph[1], "Now that I have learned 3-dimensional arrays,");
        strcpy(paragraph[2], "I can use this knowledge");
        strcpy(paragraph[3], "to write my own programs!");
    
        /* Initialize loop variables */
        j = p = 0;
        pNum = 2;    /* 2 pages */
        pGraphs = 4; /* 2 paragraphs per page */
    
        /* Allocate memory */
        Book = malloc(pNum * sizeof *Book);
        if (Book) {
            for (i = 0; i < pNum; i++) {
                /* Allocate memory */
                Book[i] = malloc(pGraphs * sizeof *Book);
    
                /* If allocation failed */
                if (Book[i] == NULL) {
                        /* Free any memory that was previously used */
                        for (k = i; k >= 0; k--) {
                            if (Book[k] != NULL) {
                                free(Book[k]);
                                Book[k] = NULL;
                            }
                        }
                        /* Free any memory that was previously used from beginning */
                        if (Book != NULL) {
                            free(Book);
                            Book = NULL;
                        }
    
                        /* Terminate program */
                        return 0;
                }
    
                for (j = 0; j < pGraphs; j++) {
                    /* Allocate memory */
                    Book[i][j] = malloc(strlen(paragraph[j]) + 1);
    
                    /* If allocation failed */
                    if (Book[i][j] == NULL) {
                        /* Free any memory that was previously used */
                        for (k = j; k >= 0; k--) {
                            if (Book[i][k] != NULL) {
                                free(Book[i][k]);
                                Book[i][k] = NULL;
                            }
                        }
                        /* Free any memory that was previously used in previous loop */
                        for (k = i; k >= 0; k--) {
                            if (Book[k] != NULL) {
                                free(Book[k]);
                                Book[k] = NULL;
                            }
                        }
                        /* Free any memory that was previously used from beginning */
                        if (Book != NULL) {
                            free(Book);
                            Book = NULL;
                        }
    
                        /* Terminate program */
                        return 0;
                    }
    
                    /* Copy data to pointer */
                    strcpy(Book[i][j], paragraph[j]);
                }
            }
        }else {
            return 0;
        }
    
        /* Print data */
        p = 0;
        printf("My two page book\n");
        for (i = 0; i < pNum; i++) {
            printf("\nPage: %i\n", i);
            for (j = p; j < (p + 2); j++) {
                printf("%s\n", Book[i][j]);
            }
            p = j;
        }
    
        /* Free Memory */
        for (i = 0; i < pNum; i++) {
            for (j = 0; j < pGraphs; j++) {
                free(Book[i][j]);
                Book[i][j] = NULL;
            }
            free(Book[i]);
            Book[i] = NULL;
        }
        free(Book);
        Book = NULL;
    
        /* End program */
        return 0;
    }
    Code 4.1: Using three-dimensional pointers

    I’ll let you decipher that one on your own. Always remember; think of this code, as a book, and it will make complete sense.

    Pointers in application
    You have learned most, if not all, of the basics pertaining pointers in the previous tutorial. Here, we’ll discuss the fact-finding situations of pointers and their importance in the programming world. This tutorial is to help you understand pointers in application, how to dissect them, and how to use them properly.

    Pointer arithmetic is also a crucial segment of learning pointers in their entirety. I briefly covered this subject in the previous tutorial, which will indeed lead to a more successful approach in pointer utilization in the near future.

    Fully understanding pointers will further help you when you run into a problem, or become confused in your current program or project. For our first approach, lets further explain the pointer usage:
    Code:
    #include <string.h>
    
    int main() {
        /* local variables */
        char ch[25];
        char *p;
    
        /* point p to ch */
        p = &ch[0];
    
        /* copy data to pointer */
        strcpy(p, "Test");
        /* concatenate data */
        memcpy(&p[4], "ing", 3);
        p[7] = '\0';
    
        /* exit program */
        return 0;
    }
    Example 5.1: Utilizing pointers in a new view

    That may seem weird, though all functions that retrieve a pointer point to where you send. Normally when you send a pointer, you don’t send its address. Since the function prototype asks for a single pointer, you send it the pointer. If we were to dissect the memcpy function, we may notice the first parameter looks different; at least while normal variable names were sent. Functions like memcpy() take a one-dimensional character array in one or more of their arguments.

    We are aware that the & operator only applies to objects in memory. Also previously learned is that p points to ch; no matter which is changed, they both correspond. Also, we are aware of the fact that “p[4]” is a single character from our array. In the cataclysmic event, we are complying with the one-dimensional array as to this extent: We are sending the object p at position 4. Any changes to this variable will proceed with and after position 4.

    If we were to take a more in-depth look, this is how the compiler perceives this: The & operator takes a one-dimensional array and then deals with the memory address; causing a “char *” to be perceived as a “char **”. Likewise with our object “p”. p[4] is a character. The & operator will then make our “char” look like a “char *”. Since we defined which location to start at “[4]”, our new “char *” will start at position 4 when converted.

    Another Example:
    Code:
    int myFunc(int *);
    
    int main() {
        /* local variables */
        int i = 3;
        int j = 2;
        int *k;
    
        /* point k to j */
        k = &j;
    
        myFunc(&i);   /* i isn’t a pointer, so send variable address */
        myFunc(k);    /* k points to j, k is already a pointer; don’t send address */
    
        /* end program */
        return 0;
    }
    
    int myFunc(int *x) {
        int z = *x;
        return z;
    }
    Example 5.2: When to send a memory address

    It is pertinent to know when and when not to send a pointer address to a function. For example, as we just saw above, consider the following:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        /* local variables */
        char ch[25];
        char *p;
    
        /* p points to ch */
        p = &ch[0];
        scanf("%s", &p); /* incorrect */
        /* same reason why */
        fgets(&p, 24, stdin); /* is incorrect */
        /* don’t send pointer address to either since p is already a pointer. */
    
        /* end program */
        return 0;
    }
    Example 5.3: Pointers address information not always needed.

    Same applies for non-pointers in this case. The character array/pointer already contains an address, and when sending to a function, don’t send the address of unless you send the location. Many don’t understand why it isn’t appropriate to send the address of a character array to scanf(). It is simple actually. The reason we don’t send it is because we want to write to its data, not its address. The reason we do send it when dealing with an integer, float, double, or other is because scanf() takes pointers to objects. If you want to store the result on a standard variable, it is imperative to precede it with the reference operator.

    Another Example:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        /* local variables */
        char ch[25];
        char *p;
    
        /* p points to ch */
        p = &ch[0];
        scanf("%24s", p);
        /* Or */
        fgets(p, sizeof ch, stdin);
    
        return 0;
    }
    Example 5.4: Send pointer address including where to point to

    This way, scanf() can write to p, not the address. The address is good when you need to directly gain access to a variable, though here we don’t need to.

    Integer variables see otherwise. When sending information to a function that needs access, it usually means it wants the address too, like scanf(). Remember, sending address information is completely different when dealing with an array or not. The difference is very obvious:
    Code:
    int main() {
        /* local variables */
        int i, j[2];
        int *p, *q;
    
        /* p points to i */
        p = &i;
        /* q points to j */
        q = &j[0];
    
        *p = 3;    /* i = 3 */
        *++(q) = 1;    /* j[1] = 1 */
    
        /* end program */
        return 0;
    }
    Example 5.5: Integers, and the difference between array’s and non-array’s

    There is a large difference between integers and character arrays. Expounding on this seems nagging, though it is what most programmers need to understand. The integer array is controlled by indices. My array[0] is a number, then my array[1] is another number. They are handled separately, and require more hand-holding. The character array is different, you have an array, and it controls the whole block. No need to set one array index at a time.

    » Pointer Techniques
    Pointers can be used in many programs, varying from the instance. You can use them to allocate memory, point to other variables, change data from a specified address, and so on and so forth. It really depends on where you use them, and what they are being used for. For example, if you wanted to send a two-dimensional array to a function and allocate it there; it would be somewhat impossible to send the 2-D pointer and memory address and allocate it there. There are ways around this though, for instance we would send our 2-D pointer to a function. Then we would create a temporary 2-D pointer inside our separate function and allocate it there. Tell our sent object to equal the temporary variable, and we are on our way.

    Here is an example:
    Code:
    #include <stdlib.h>
    
    void alloc2D(char ***, int, int);
    
    int main() {
        /* Local variables */
        int i;
        char **string = NULL;
    
        alloc2D(&string, 3, 5);
    
        /* If allocation failed */
        if (string == NULL)
            return 0;
    
        /* Free memory */
        for (i = 0; i < 3; i++)
            free(string[i]);
        free(string);
    
        /* End program */
        return 0;
    }
    
    void alloc2D(char ***str, int row, int column) {
        /* Local variables */
        int i;
        char **temp = NULL;
    
        /* Allocate temporary variable */
        temp = malloc(row * sizeof *temp);
        if (temp)
            for (i = 0; i < row; i++)
                temp[i] = malloc(column + 1);
        /* Object of str now links to temp */
        *str = temp;
    }
    Code 5.1: Allocating a 2-dimensional array by passing pointers.

    Conclusion
    In conclusion of this segment, there are many ways pointers can be utilized in programs. This tutorial is just here to provide information on pointers, and how they work. With the fundamentals, it should not be difficult to debug your own programs and figure out why they may be performing the way it is.


    - Stack Overflow
    Last edited by Stack Overflow; 02-04-2005 at 03:10 PM. Reason: Fixed. Tidy grammar.
    Segmentation Fault: I am an error in which a running program attempts to access memory not allocated to it and core dumps with a segmentation violation error. This is often caused by improper usage of pointers, attempts to access a non-existent or read-only physical memory address, re-use of memory if freed within the same scope, de-referencing a null pointer, or (in C) inadvertently using a non-pointer variable as a pointer.

  7. #7
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    New York
    Posts
    1,905


    Stack Overflow.......you are......amazing....


  8. #8
    ---
    Join Date
    May 2004
    Posts
    1,379
    lol Stack Overflow is cheating

  9. #9
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Slow night Stack?

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    This is good stuff, which should be made part of the FAQ IMO.

    > printf(ptr);
    Very poor use of printf. Never pass a derived string to printf as the first parameter, because if ever a % character makes it into the string, that's when all the fun and games start.
    Use fputs(ptr,stdout); or printf("%s",ptr) to print such strings.

    > Book = malloc(sizeof **Book * pNum);
    Should be only sizeof *Book

    > scanf("%25s", p);
    1. Your HTML-iser changes regular source code quotes into something else, so code examples cannot be copy/pasted directly into an editor.
    2. "%25s" on a buffer of 25 chars leads to overflow. scanf converts up to 25 chars, then appends a \0 (26 in all). This is quite annoying when compared to fgets() which does allow for the \0 in the size you specify.

    > int[/color] main() {
    Tagging going amiss here.

    > temp[i] = (char *)malloc(column * sizeof(**temp));
    Oooh, casting malloc, not good C.

    Writing it in a consistent style throughout would be better IMO
    temp[i] = malloc(column * sizeof(*temp[i]));

    > ptr[i] = malloc(strlen(word[i]) + 1 * (sizeof **ptr));
    Again on the style, plus the operator precedence is all wrong
    ptr[i] = malloc( (strlen(word[i])+1) * (sizeof *ptr[i]) );

    The general style of p = malloc( howmany * sizeof *p );
    should be used for all malloc calls.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Registered User
    Join Date
    Mar 2004
    Posts
    494
    great! you all here doing a great job helping us
    When no one helps you out. Call google();

  12. #12
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >lol Stack Overflow is cheating
    Yes, but cheating in a good way.
    My best code is written with the delete key.

  13. #13
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Regarding Example 1.4:
    Code:
    #include <stdio.h>
    
    int main() {
        int n[5] = {1,2,3,4,5};
        int *ptr;
    
        /* points to n[0]*/
        ptr = &n[0];
        printf("ptr now points to n[%d] whose value is %d\n", (int)(ptr - n), *ptr);
    
        /* points to n[1] */
        *(ptr+1); /* this expression references n[1], but ptr remains the same */
        printf("ptr now points to n[%d] whose value is %d\n", (int)(ptr - n), *ptr);
    
        /* points to n[2] */
        (*ptr)++; /* this increments what ptr is pointing to, and ptr remains the same  */
        printf("ptr now points to n[%d] whose value is %d\n", (int)(ptr - n), *ptr);
    
        /* However, increments the value of the content of the location pointed by ptr */
        ++*ptr; 
        printf("ptr now points to n[%d] whose value is %d\n", (int)(ptr - n), *ptr);
    
        return 0;
    }
    
    /* my output
    ptr now points to n[0] whose value is 1
    ptr now points to n[0] whose value is 1
    ptr now points to n[0] whose value is 2
    ptr now points to n[0] whose value is 3
    */
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  14. #14
    Alright,

    Thanks guys. I will edit my original post and make the necessary changes.

    Though, I had a late night last night and started to slip up on my presentation. My apologies. I occasionaly fix stuff. Little things I keep skipping over, and adding [color] tags too. Thanks Salem for pointing that out!

    Note: All examples have been modified. And can now compile sucessfully with -Wall, -pedantic, -ansi, and -std=c89 GCC compiler flags. Remember, I made a few examples of what not to do, so of course those may return warnings or errors.


    - Stack Overflow
    Last edited by Stack Overflow; 02-04-2005 at 12:19 PM.
    Segmentation Fault: I am an error in which a running program attempts to access memory not allocated to it and core dumps with a segmentation violation error. This is often caused by improper usage of pointers, attempts to access a non-existent or read-only physical memory address, re-use of memory if freed within the same scope, de-referencing a null pointer, or (in C) inadvertently using a non-pointer variable as a pointer.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Using pointers to pointers
    By steve1_rm in forum C Programming
    Replies: 18
    Last Post: 05-29-2008, 05:59 AM
  2. function pointers
    By benhaldor in forum C Programming
    Replies: 4
    Last Post: 08-19-2007, 10:56 AM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  4. Staticly Bound Member Function Pointers
    By Polymorphic OOP in forum C++ Programming
    Replies: 29
    Last Post: 11-28-2002, 01:18 PM