1

I just confused with these codes.

int state[arraySize] = {};

And

int *state;
state = (int*)calloc(arraySize,sizeof(int));
//............
free(state);

What's the difference between them? As I need to collect some figures for my program. And each time run with different variables which may affect the array size. So I cannot use an array immediately. But when I changed my array to the (2), the result of my code appears differently and sometimes seems to entered a dead cycle.

CashCow
  • 30,981
  • 5
  • 61
  • 92
neilyo
  • 41
  • 2
  • Don't cast pointers on allocation... – roelofs Aug 13 '14 at 14:45
  • 2
    You have to cast pointers on allocation in C++. – Robert Allan Hennigan Leahy Aug 13 '14 at 14:46
  • A pointer is something that points to something else. An array is a contiguous sequence of things. – juanchopanza Aug 13 '14 at 14:46
  • @RobertAllanHenniganLeahy - my bad - was just looking at a C question. – roelofs Aug 13 '14 at 14:46
  • 3
    Just use `std::vector`, and use this question as academic interest. – MatthiasB Aug 13 '14 at 14:47
  • 1
    The relationship between arrays and pointers can be confusing. Anyone who tells you that arrays are really pointers is absolutely wrong. The rules are pretty much the same in C as in C++; section 6 of the [comp.lang.c FAQ](http://www.c-faq.com/) does an excellent job of explaining it. – Keith Thompson Aug 13 '14 at 14:47
  • 1
    What do you mean 'entered a dead cycle'? – roelofs Aug 13 '14 at 14:47
  • @RobertAllanHenniganLeahy: "*You have to cast pointers on allocation in C++*" -- Not if you use `new[]`, which you should. – Keith Thompson Aug 13 '14 at 14:48
  • "`state = (int*)calloc(arraySize,sizeof(int));`" Who ever teaches you *this* as C++ should be beaten with a stick. (For the pedants: Yes, I know it is legal C++ code, but still...) – Baum mit Augen Aug 13 '14 at 14:48
  • You shouldn't use `new`. – Robert Allan Hennigan Leahy Aug 13 '14 at 14:49
  • If it is a C++ question - the use of calloc/free a bit confusing since it covers PODs but doesn't conver objects. Perhaps the same code sample rewritten with new/delete will lead to different results. – Tanuki Aug 13 '14 at 14:49
  • @CashCow: It's valid C90, C99, C11, and C++. – Keith Thompson Aug 13 '14 at 15:02
  • @RobertAllanHenniganLeahy: Do you mean that you should use container classes rather than `new`? I hope you'd agree that `new` is better than `calloc`. – Keith Thompson Aug 13 '14 at 15:02
  • I wouldn't agree that either `new` or `calloc` are superior. They're different tools for different jobs, and both should be proscribed. – Robert Allan Hennigan Leahy Aug 13 '14 at 15:15
  • @RobertAllanHenniganLeahy: Proscribed in favor of what? I *think* I know what you mean, but you haven't actually said what *should* be used. (And please include my name following an @ sign if you reply; I didn't get a notification for your most recent comment.) – Keith Thompson Aug 13 '14 at 15:35
  • @KeithThompson if arraySize is not a constant I do not think it is valid C90, and not sure about C++ either. – CashCow Aug 13 '14 at 16:05
  • @CashCow: It's a code fragment; without the declaration of `arraySize` it's not valid in any language I know of. – Keith Thompson Aug 13 '14 at 16:15
  • @KeithThompson: [`std::make_unique`](http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique). It's irrelevant that the standard doesn't provide this until C++14, one can trivially provide this functionality in minutes. – Robert Allan Hennigan Leahy Aug 13 '14 at 23:42
  • @RobertAllanHenniganLeahy: Ok, I'm not familiar with it but I'll take your word for it. Do you see that your earlier comment "You shouldn't use `new`" wasn't particularly clear? For all I could tell at the time, you could have been advocating `malloc()`. – Keith Thompson Aug 14 '14 at 00:28
  • This post should be reopened as it is now about C, not C++. – qwr Jun 18 '21 at 18:33

5 Answers5

2

A pointer points to another area of memory. In your second example state is not an array, it points to an array. I.e. by following (or dereferencing) the pointer you find an array.

An array, on the other hand, is an area of memory large enough to accommodate some number of some type of element. In your first example state is a region of memory which may hold arraySize ints.

What's confusing is that in many instances you can name an array, and a pointer to the first element of the array will be the result. This is the array-to-pointer decay.

  • 10
    `state` doesn't point to an array; it points to the first element of an array. We can use pointer arithmetic to access the other elements of the array. – Keith Thompson Aug 13 '14 at 14:49
2

C-FAQ 6.2:

The array declaration char a[6] requests that space for six characters be set aside, to be known by the name a. That is, there is a location named a at which six characters can sit. The pointer declaration char *p, on the other hand, requests a place which holds a pointer, to be known by the name p. This pointer can point almost anywhere: to any char, or to any contiguous array of chars, or nowhere.
As usual, a picture is worth a thousand words. The declarations

char a[] = "hello";
char *p = "world";

would initialize data structures which could be represented like this:

enter image description here

In case of

int *state = calloc(arraySize,sizeof(int));  

a chunk of memory is allocated on heap. state is now pointing to the first memory cell of that chunk. The rest of the memory cell can be visited by using pointer arithmetic. If state is pointing at memory address 0x100 then state + 1 will point 0x104 (taking int of 4 bytes).

state       -----> Points to the first memory cell of the allocated memory block.
state + 1   -----> Points to the second memory cell of the allocated memory block.
state + 2   -----> Points to the third memory cell of the allocated memory block.  
...
...

You should note that: Pointer arithmetic and array indexing are equivalent in C, pointers and arrays are different.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • Yes, sort of, but his case assigned the pointer to memory allocated on the free-store through calloc. – CashCow Aug 13 '14 at 16:04
1

This looks more like C than C++. The differences are:

  1. The first one is of a "fixed" size during its lifetime. C99 allows arraySize to be a variable but it is still "automatic" in the call-stack.

  2. The second one is a pointer and the call of calloc points it to some allocated memory which will remain in storage until the call to free. That free could take place after the function has returned.

the first state is an r-value. You cannot assign state to point somewhere else. You cannot safely return it from your function either.

If you take sizeof(state) on both you will also see that the first will be sizeof(int)*arraySize the second will be the standard size of a pointer. If arraySize is 50 and sizeof(int) is 4 and sizeof(int *) is 8 say, the first will be 200 the second 8.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
CashCow
  • 30,981
  • 5
  • 61
  • 92
1

As already stated a pointer is simply a region of memory that can be referenced that holds the address of another location in memory (or the 'heap' to be more precise) that contains actual data. An array on the other hand is an aggregate data type meaning that it contains a collection of elements (individual cubbyholes of the same data type) normally in contiguous regions of memory. The first element of the array is the pointer to the beginning of the structure. Let's put all of this into some code.

Pointer

There are multiple ways that pointers can be used depending on how flexible you want them to be. The simplest way is to have a pointer point to a variable, say

int a = 1;
int* a_ptr = &a;

int b = *a_ptr;  /* b is initialized to 1 via the pointer to a. */

Array

An array, on the other hand is also a very simple concept. Bare in mind that the address of the first element in the array is the stating address of the overall structure.

When we access an array we use the conventional notation:

int someArr[3] = {0, 2, 4};

someArr[0]; /* 0 */
someArr[1]; /* 2 */
someArr[2]; /* 4 */

but we can also use the regular pointer dereferencing syntax to access an array:

*(someArr); /* 0 */
*(someArr + 1); /* 2 */
*(someArr + 2); /* 4 */

which clearly exposes how closely related arrays are to pointers. As an explanation of the last section of code:

*(someArr + n) where 'n' is the number of bytes of array type that is advanced in memory to retrieve the value pointed to, so:

*(someArr + n) is the same as *(someArr + (n * [size of array element type])) to find the value of array element 'n'.

ButchDean
  • 70
  • 6
0

The first one the array is fully controlled by the scope. It will allocate the needed memory correctly and when the variable goes out of escope the memory will be freely automatically.

The second one you have to control the memory by yourself. It does not have a defined scope, although if you do not destroy it when it gets out of reach, it will leave a memory leak.

To help you more about the dead cycle, I need more info about what you are doing with the array or array-pointer.

  • 2
    What "array-pointer" are you referring to? `int *state;` defines a pointer to a single `int` object. A pointer to an array would be something like `int (*a)[42];`. (And you haven't really explained the difference between an array and a pointer.) – Keith Thompson Aug 13 '14 at 15:37
  • Well, he asked the difference between the first code and second code, not the difference of a pointer and an array. The second example is a pointer to an array. – Augusto César Martins Gil Aug 13 '14 at 17:18
  • 1
    The question's title is "Difference between pointer and array in C". And no, the second example is not a pointer to an array; it's a pointer to *the first element of* an array. C does have pointers to arrays; there are none in the OP's code. – Keith Thompson Aug 13 '14 at 17:35