Reputation: 1811
Here consider the following sample of code:
int *a = malloc(sizeof(int) * n);
Can this code be used to define an array a containing n integers?
Upvotes: 3
Views: 10737
Reputation: 81105
In the language the Standard was written to describe (as distinct from the language that would be described by a pedantic literal reading of it), the intention was that malloc(n) would return a pointer that would, if cast to a T*
, could be treated as a pointer to the first element of a T[n/sizeof T*]
. Per N1570 7.22.3:
The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement and then used to access such an object or an array of such objects in the space allocated (until the space is explicitly deallocated).
The definition of pointer addition and subtraction, however, do not speak of acting upon pointers that are "suitably aligned" to allow access to arrays of objects, but rather speak of pointers to elements of actual array objects. If a program accesses space for 20 int
objects, I don't think the Standard does actually says that the resulting pointer would behave in all respects as though it were a pointer to element [0] of an int[20]
, as distinct from e.g. a pointer to element [0][0] of an int[4][5]
. An implementation would have to be really obtuse not to allow it to be used as either, of course, but I don't think the Standard actually requires such treatment.
Upvotes: 0
Reputation: 20631
Interpreting your question very literally, the answer is No: To "define an array" means something quite specific; an array definition looks something like:
int a[10];
Whereas what you have posted is a memory allocation. It allocates a space suitable for holding an array of 10 int
values, and stores a pointer to the first element within this space - but it doesn't define an array; it allocates one.
With that said, you can use the array element access operator, []
, in either case. For instance the following code snippets are legal:
int a[10];
for (int i = 0; i < 10; i++) a[i] = 0;
and
int *a = malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) a[i] = 0;
There is a subtle difference between what they do however. The first defines an array, and sets all its elements to 0. The second allocates storage which can hold an equivalently-typed array value, and uses it for this purpose by initialising each element to 0.
It is worth pointing out that the second example does not check for an allocation error, which is generally considered bad practice. Also, it constitutes a potential memory leak if the allocated storage is not later freed.
Upvotes: 3
Reputation: 263217
int *a = malloc(sizeof(int) * n);
Can this code be used to define an array a containing n integers?
That depends on what you mean by "define an array".
A declaration like:
int arr[10];
defines a named array object. Your pointer declaration and initialization does not.
However, the malloc
call (if it succeeds and returns a non-NULL
result, and if n > 0
) will create an anonymous array object at run time.
But it does not "define an array a
". a
is the name of a pointer object. Given that the malloc
call succeeds, a
will point to the initial element of an array object, but it is not itself an array.
Note that, since the array object is anonymous, there's nothing to which you can apply sizeof
, and no way to retrieve the size of the array object from the pointer. If you need to know how big the array is, you'll need to keep track of it yourself.
(Some of the comments suggest that the malloc
call allocates memory that can hold n
integer objects, but not an array. If that were the case, then you wouldn't be able to access the elements of the created array object. See N1570 6.5.6p8 for the definition of pointer addition, and 7.22.3p1 for the description of how a malloc
call can create an accessible array.)
Upvotes: 7
Reputation: 3538
Yes. That is exactly what malloc()
does.
The important distinction is that
int array[10];
declares array
as an array object with enough room for 10 integers. In contrast, the following:
int *pointer;
declares pointer
as a single pointer object.
It is important to distiguinsh that one of them is a pointer and that the other as an actual array, and that arrays and pointers are closely related but are different things. However, saying that there is no array in the following is also incorrect:
pointer = malloc(sizeof (int) * 10);
Because what this piece of code does is precisely to allocate an array object with room for 10 integers. The pointer pointer
contains the address of the first element of that array.(C99 draft, section 7.20.3 "Memory management functions")
Upvotes: 4
Reputation: 121357
int *a = malloc(sizeof(int) * n);
Assuming malloc()
call succeeds, you can use the pointer a
like an array using the array notation (e.g. a[0] = 5;
). But a
is not an array itself; it's just a pointer to an int
(and it may be a block of memory which can store multiple int
s).
Your comment
But I can use an array a in my program with no declaration otherwise
suggests this is what you are mainly asking about.
In C language,
p[i] == *(p + i) == *(i + p) == i[p]
as long as one of i
or p
is of pointer type (p
can an array as well -- as it'd be converted into a pointer in any expression). Hence, you'd able to index a
like you'd access an array. But a
is actually a pointer.
Upvotes: 5