-3

What is the time complexity of declaring and defining, but not initializing, an array in C? For what reason is the answer the case?

I am interested in the time complexity at both compile and run time, but more so run time.

Here is an example of a program with such an array:

int main () 
{
    int n[ 10 ]; /* n is an array of 10 integers */
    return 0;
}

If it is not O(1), constant time, is there a language that does declare and define arrays in constant time?

Rob
  • 39
  • 1
  • 5
  • 7
    What? ........... – Martin James May 02 '16 at 21:06
  • Why do you ask Rob? :) – gsamaras May 02 '16 at 21:06
  • 1
    Look at http://stackoverflow.com/questions/16064820/what-is-the-time-complexity-of-array-initialization – DarthRubik May 02 '16 at 21:07
  • 7
    "declaring" an array is a compile-time concept not a run-time cost. Without initialization, the cost of creating an array is 0(1) – kmdreko May 02 '16 at 21:07
  • 2
    The time complexity of the declaration per se is O(1) from the language standpoint, because it essentially is zero without initialization. Of course, if you declare a big array or many small arrays the OS will take more time to create the program image in memory (to allocate space for the program & etc), but this is essentially external to the program itself. – Fabio Ceconello May 02 '16 at 21:09
  • 2
    If you declare a large array on the stack, like int x[1000000000000], you run the risk of blowing out the stack, and your program not running at all. – bruceg May 02 '16 at 21:10
  • Did you mean *defining* an array? – M.M May 02 '16 at 21:11
  • 3
    How about you choose one of the two languages? C and C++ are distinct. – fuz May 02 '16 at 21:11
  • 2
    The answer is O(42). – callyalater May 02 '16 at 21:14
  • @FabioCeconello The question is tagged C++, so it can actually be O(n). – juanchopanza May 02 '16 at 21:14
  • Apologies for the confusion everyone - I have updated the question to involve only C arrays. However, why is this getting down voted so much? Can I improve it somehow? I am just curious about the time complexity of declaring versus intializing (which I know is O(n)). – Rob May 02 '16 at 21:15
  • 1
    @callyalater Good that O(42) is equal to O(1) :D – deviantfan May 02 '16 at 21:15
  • @Rob Then please make it clear too that you meant defining. – deviantfan May 02 '16 at 21:16
  • As a local variable at most the stack pointer(or implementation equivalent) is moved. In C++ Maybe N default constructors are called. Dynamically, the OS may have to hunt for a free memory block. There is subtlety here, but OP has removed C++ from the mix, and the OS allocating memory may be a problem for the program, but is outside the program's scope. – user4581301 May 02 '16 at 21:18
  • @Rob, you need to add more detail ie are we talking about compile time, runtime, how was it declared, is it C or C++ etc. Show the specific example you want to discuss. – Harry May 02 '16 at 21:20
  • I hope my edits have cleared up any confusion so my question can be answered now. Let me know if not! – Rob May 02 '16 at 21:30
  • That's initialization on the stack. – Harry May 02 '16 at 21:31
  • How do datastructures themselves have a time-complexity? – too honest for this site May 02 '16 at 21:33
  • @Olaf It's not the datastructure, but it's allocation... – Eugene Sh. May 02 '16 at 21:36
  • @EugeneSh.: As the C standard does not enforce a specific allocation scheme, how would that to be answered? – too honest for this site May 02 '16 at 21:52

3 Answers3

3

The language doesn't specify this. But in typical implementations, space for all local variables in a block is allocated simply by adjusting the stack pointer by the total size of all the variables when entering that block, which is O(1). Arrays are simply included in that total size, and it's calculated at compile time. VLAs are not allocated when the block is entered, the allocation is delayed until the execution of the declaration (since it depends on a variable which must be assigned first), but it's still just an O(1) operation of adjusting the SP register.

I think many implementations actually allocate all the space for a function when entering the function, rather than adjusting the SP for each block. But variables that exist in blocks that do not overlap may share the same memory in the stack frame. But this is not really relevant for the question asked, unless you're wondering if there's a difference between

int a[10];
int b[10];
// code that uses a and b

and

int a[10];
{
    int b[10];
    // code that uses a and b
}

The compile-time complexity is O(1) for each variable (it just needs to look up the size of the datatype, and multiply by the size if it's an array), so O(n) where n is the number of local variables.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • @SteveSummit I don't think the VM actually has to do anything until you actually access something in the new stack frame. And then it depends on whether that causes a page fault. As you mention in your answer, this may be amortized with other activities -- if the array is on the same page as other data, the array itself adds no cost. – Barmar May 02 '16 at 21:42
  • Problem is the C standard does not enforce a specific memory management scheme. – too honest for this site May 02 '16 at 21:53
  • 1
    @Olaf I addressed that with the first sentence of my answer. – Barmar May 02 '16 at 21:54
  • Well – not exactly. You express uncertainty, which I tried to clarify. – too honest for this site May 02 '16 at 21:57
  • OK, I've changed it to an absolute. Your comment made it sound like I totally ignored the issue. – Barmar May 02 '16 at 21:59
3

This is a strange and probably unanswerable question. Normally complexity analysis and "big O" notation are applied to algorithms, not so much implementations. But here you're essentially asking entirely about implementation, and of the non-algorithmic, "noise" or "overhead" activities of allocating arrays.

Defining and declaring are compile-time concepts, and I've never heard big-O applied to compile-time activities.

At run time, there may be some work to do to cause the array to spring into existence, whether or not it's initialized. If it's a local ("stack") array, the OS may have to allocate and page in memory for the new function's stack frame, which will probably be more or less O(n) in the array's size. But if the stack is already there, it will be O(0), i.e. free.

If the array is static and/or global, on the other hand, it only has to get allocated once. But, again, the OS will have to allocate memory for it, which might be O(n). The OS might or might not have to page the memory in -- depends on whether you do anything with the array, and on the OS's VM algorithm. (And once you start talking about VM performance, it gets very tricky to define and think about, because the overhead might end up getting shared with other processes in various ways.)

If the array is global or static, and if you don't initialize it, C says it's initialized to 0, which the C run-time library and/or OS does for you one way or another, which will almost certainly be O(n) at some level -- although, again, it may end up being overlapped or shared with other activities in various complicated or unmeasurable ways.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
1

In C, the cost of instantiating a variable at run time (whether a scalar or an array) is (usually) down in the noise, although it really depends on the underlying platform. For example, setting aside space for auto variables on an x86 platform is (usually) done by simply adjusting the stack pointer:

subq    $X, %rsp

where X is the amount of storage required for all local variables in the function. So it takes the same amount of time whether X is 4 or 4K1.

Storage for static variables may be allocated from within the program image itself, such that the storage is set aside as soon as the program is loaded into memory (making it effectively zero-cost at runtime).

Or not.

Big O notation doesn't really apply here; the exact mechanisms for allocating storage can vary a lot based on the implementation, and much of it is out of your control. Space is usually the limiting factor here, not time.


  1. Modulo page faults or other memory subsystem functions that are beyond our control.

John Bode
  • 119,563
  • 19
  • 122
  • 198