Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Basic C, pointers into arrays?

  1. Jul 28, 2010 #1
    So I'm learning C, and I think I'm doing pretty well so far. Anyway, I'm up to Arrays, and some code that was posted in the tutorial is this:

    Code (Text):
    #include <stdlib.h>

    int main()
        int*    myArray = malloc( sizeof(int) * 20 );    // could write int myArray[20]; instead.

        myArray[5] = 42;

        // ... do something else here.

        free( myArray ); // Give up ownership once we're done.

        return 0;
    The thing that's confusing me is this. So first, you define a pointer variable, (myArray), and you make it point to some memory with malloc. So now, the pointer contains the address to some data that can hold 20 ints. All correct so far?

    Anyway, when myArray[5] comes along, they simply treat the pointer like an array. What I don't i understand is this. How can a variable holding a pointer to some data be an array? I thought you would have to declare an array, and then tell it to go into the data that you just allocated with malloc.

    Or, is it not really an array? By saying myArray[5], are you simply referring to the sixth block of memory in the myArray section which was just allocated?

    I hope I didn't word this question in a confusing way, I'm just trying to go through C making sure I understand everything instead of rushing through.

  2. jcsd
  3. Jul 28, 2010 #2
    Correct. myArray is a pointer to a block of memory, and myArray[5] is the element in that block with an offset 5*sizeof(int) from the beginning.

    If you were to write

    Code (Text):

    int myArray[20];
    that code would really have dual roles. It would allocate a 20-unit array on the stack and assign "myArray" to be the pointer to the beginning of that array. You could even access an element of that array by writing
    Code (Text):

    // or
    regardless of whether it was allocated as a local array on the stack or allocated using malloc().

    The only functional difference between

    Code (Text):

    int*    myArray = malloc( sizeof(int) * 20 );
    Code (Text):

    int myArray[20];
    is that, in the first case, sizeof(myArray) is the size of the pointer (probably 4), and, in the second case, it's the size of the entire array (most likely 80). And that, in the first case, you're responsible for freeing the memory, and, in the second case, the memory is automatically released when the array goes out of scope.
    Last edited: Jul 28, 2010
  4. Jul 28, 2010 #3
    Thanks a lot, that answer really helped me out. One more question came from your post though.

    So to be clear, when you declare an array with "int myArray[6]", for example, the size of myArray is the entire array, so chances are 24 bytes? However, if I defined it with malloc, the size of myArray is only the pointer to the first block of my 24 bytes?

    Another thing, I ran this code to test what you said:

    Code (Text):
    #include <stdio.h>
    #include <stdlib.h>

    int     main()
        int * myArray = malloc( sizeof(int) * 20 );
        int size = sizeof(myArray);
        printf("%d", size);
        return 0;
    However it returns a value of 8. How come the pointer is 8 bytes, I thought they were 4?
  5. Jul 28, 2010 #4
    You must be using a 64-bit operating system. (More specifically, a 64-bit OS and a compiler in 64-bit mode.) In that case, the pointer would be 8 bytes.
    Last edited: Jul 28, 2010
  6. Jul 28, 2010 #5
    Yeh, that makes sense, I'm using a 64bit mac. Just out if interest, why are pointers larger on 64 bit?
  7. Jul 28, 2010 #6
    That's the whole point of 64 bit. Or most of it. A 32-bit pointer can't address more than 4 gigabytes of memory.
  8. Jul 28, 2010 #7
    Ah, that's just answered a question I've wanted to know for years! I always wondered why 32 bit processors were limited to a certain amount of ram.

    I'm also learning about strings at the moment, and instead of cluttering up the forum with another thread, I thought I'd carry it on here (as they are vaguely related I guess).

    So, from I understand, you can define a string by using:
    Code (Text):
    char * stringName = "Text here!";
    And that creates a variable that you can use as a string, print it with printf and %s, and compare with strcmp(). Correct?

    My first question is, what actually happens here? Essentially, by defining char * stringName, we're making a pointer variable called stringName which can hold the address of one char. So why can you just stick a load of text in a pointer variable? Is C doing something secretly here?

    Also, another way of declaring a string is:
    Code (Text):
    char newString[10]
    which makes a string which can hold 9 characters (plus the zero at the end to tell the compiler the string has finished). However, to define the characters in this string, you have to go and define them like so:
    Code (Text):
    newString[0] = 'H';
    newString[1] = 'E';
    Is that right? If so, why would you use the second method of creating strings? To me, it just seems more cumbersome to have to define all the characters individually, but i assume there must be a use to it or else no one would use it at all.

    I apologise for the long question, but strings just seem a bit weird to me at the moment. For someone who's used to php and javascript, this is a very odd concept to take in!

    Thanks for all your help.
  9. Jul 28, 2010 #8
    You're not supposed to use char * stringName = "Text here!" . Even if the compiler allows you, it's just wrong. You should write const char * stringName = "Text here!" . When you do that, your program creates a global string somewhere in memory and assign the pointer to that string to "stringName". It is not appropriate to modify those strings (IIRC, the outcome is not even defined by the standard), thus the correct thing to do is to declare the pointer as "const" so it can only be used for reading.

    You can do

    Code (Text):
    char newString[10] = "Text here";
    then it's basically the same thing as what we did with ints, and the array will be preloaded with the string. Or you can just allocate it on the stack without initializing it

    Code (Text):
    char newString[10];
    and then fill the elements individually.
  10. Jul 28, 2010 #9
    Ok, so I should only use const char * stringName = "Text here!" to store a string that I'm going to refer to later, and not change. Correct?

    Hopefully my final query, if I defined a string using char newString[10] = "Text here";, how would I go about changing the contents of that string? Is the only way to go through individual characters and change them?
  11. Jul 28, 2010 #10
    You can modify individual characters, or you can use standard library functions such as strcpy:

    Code (Text):

    strcpy(newString, "New text");
    const char* str1 = "New ";
    const char* str2 = "Text";
    strcpy(newString, str1);
    strcat(newString, str2);
    However, you must be careful, because you only have room for 10 characters in the array and you should take care not to overshoot the end.
  12. Jul 28, 2010 #11
    Just to add something here: If you want to work with dynamic arrays, then look at the alloc, realloc and free functions. It might be very relevant now, since it also includes some work on pointers.
  13. Jul 28, 2010 #12
    Ok, thanks a lot to both of you, I've learnt a lot today! I shall be looking in to alloc, realloc and free very soon. Thanks again :D
  14. Jul 28, 2010 #13
    x[y] is shortand for *(x+y), and thus for *(y+x), and therefore to y[x]. You can actually index by index[array].

    That aside, the only difference between static arrays and const pointers is at compile time, not at runtime. &array and sizeof(array) are the two differences that are often cited, but these are compile time things only, not runtime. The compiler can simply replace sizeof(array) with for instance 10*sizeof(int) if you declared int array[10]; in the same lexical block, it doesn't count any more outside of the lexical block, because outside of it has become runtime info, and at runtime an array is just a const pointer to the first element of that array.
  15. Jul 28, 2010 #14


    User Avatar
    Homework Helper

    If the declaration for myArray is done outside of any function, or if it's declared as "static", then it becomes part of the programs data section (usually the "uninitialized" data section of a program), and memory for is allocated at program load time (before the program is executed).
  16. Jul 28, 2010 #15
    That, and it's a const pointer, also an important difference, you can't assign to a static array the same way you can to a 'dynamic array'.
  17. Jul 29, 2010 #16


    User Avatar
    Homework Helper

    Static just means the name is local to the source file and that the variable is initialized to zero. I'm not sure what you mean by assign, but there is no issue assigning values to elements of a static array, such as
    Code (Text):

    static int myArray[20];
        myArray[3] = 5;
  18. Jul 29, 2010 #17
    I mean you can't use:

    Code (Text):
    int myArray[] = {1,2,3,4,5};
    int x = 3;
    myArray = &x;
    Which you can do with variables that house pointers that are not const. As in from Malloc.

    With static I mean the general term which some sources call 'lexical', as in static/lexical types versus dynamic types et cetera. With static in computer science people usually mean 'determined at compile time' whereas with dynamic people mean 'determined at runtime'.
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook