Home > Back-end >  Is it possible to assign data to this "static array" in C using for-loop?
Is it possible to assign data to this "static array" in C using for-loop?

Time:03-03

There is a line of code inside a method similar to:

static char data[] = "123456789";

I want to fill the above data array with a million characters not just nine. But since it is tedious to type it, I want to do that in for loop.

Is that possible to do it keeping it as "static char data[]"?

edit:

static char data[1000000];

for(int i=0; i<1000000; i  )
{
    data[i] = 1;
}

CodePudding user response:

There are multiple ways to achieve this in C:

  • you can declare the global static array as uninitialized, write an initialization function and call this function at the beginning of the program. Unlike C , C does not have a standard way to invoke such an initialisation function at program startup time, yet some compilers might provide an extension for this.

    static char data[1000000];
    
    void init_data(void) {
        //the loop below will generate the same code as
        //memset(data, 1, sizeof data);
        for (int i = 0; i < 1000000; i  ) {
            data[i] = 1;
        }
    }
    
    int main() {
        init_data();
        ...
    }
    
  • you can change your program logic so the array can be initialized to 0 instead of 1. This will remove the need for an initialization function and might simplify the code and reduce the executable size.

  • you can create the initializer for the array using an external program and include its output:

    static char data[1000000] = {
    #include "init_data.def"
    };
    
  • you can initialize the array using macros

    #define X10(s)  s,s,s,s,s,s,s,s,s,s
    #define X100(s) X10(s),X10(s),X10(s),X10(s),X10(s),X10(s),X10(s),X10(s),X10(s),X10(s)
    #define X1000(s) X100(s),X100(s),X100(s),X100(s),X100(s),X100(s),X100(s),X100(s),X100(s),X100(s)
    #define X10000(s) X1000(s),X1000(s),X1000(s),X1000(s),X1000(s),X1000(s),X1000(s),X1000(s),X1000(s),X1000(s)
    #define X100000(s) X10000(s),X10000(s),X10000(s),X10000(s),X10000(s),X10000(s),X10000(s),X10000(s),X10000(s),X10000(s)
    
    static char data[1000000] = {
        X100000(1), X100000(1), X100000(1), X100000(1), X100000(1),
        X100000(1), X100000(1), X100000(1), X100000(1), X100000(1),
    };
    

Note however that this approach will be a stress test for both your compiler and readers of your code. Here are some timings:

 clang: 1.867s
 gcc: 5.575s
 tcc: 0.690s

The last 2 solutions allow for data to be defined as a constant object.

CodePudding user response:

Is that possible to do it keeping it as "static char data[]"?

No, you have to specify the size explicitly. If you wish to compile-time initialize the array rather than assigning to it in run-time with a for loop or memset, you can use tricks such as this.

Another option might be to use dynamic allocation with malloc instead, but then you have to assign everything in run-time.

CodePudding user response:

You can define statically allocated arrays in various ways, incidentally, this has nothing to do with the static keyword, see this if you need more information about static variables. The following discussion won't have anything to do with that, hence I will be omitting your static keyword for simplicity.

An array declared as:

char data[] = "123456789";

is allocated in the stack in the compile time. Compiler can do that since the size of the array is implicitly given with the string "123456789" to be 10 characters, 9 for the data and 1 for the terminating null character.

char data[];

On the other hand, will not compile, and your compiler will complain about missing array sizes. As I said, since this declaration allocates the array in the compile time, your compiler wants to know how much to allocate.

char data[1000000];

This on the other hand will compile just fine. Since now the compiler knows how much to allocate. And you can assign elements as you did in a for loop:

for(int i=0; i<1000000; i  )
{
    data[i] = 1;
}

Note: An array of million chars has quite a respectable size, typically 1Mb, and may overflow your stack. Whether or not that it actually will depends on pretty much everything that it can depend on, but it certainly will rise some eyebrows even if your code works fine. And eventually, if you keep increasing the size you will end up overflowing your buffer.

If you have truly large arrays you need to work with, you can allocate them on the heap, i.e., in the wast empty oceans of your ram.


The part above hopefully should have answered your question. Below is simply an alternative way to assign a fixed value, such as your (1), to a char array, instead of using for loops. This is nothing but a more convenient way (and perhaps a better practice), you are free to ignore it if it causes confusion.

#include <string.h>
#define SIZE 100000

// Create the array, at this point filled with garbage.
static char data[SIZE];

int main( void )
{
    // Initialise the array: assigns *integer 1* to each element.    
    memset( data, 1, sizeof data )

    //^___ This single line is equivalent of:
    // for ( int i = 0; i < SIZE; i   )
    // {
    //     data[i] = 1;
    // }
    
    .
    .
    .

    return 0;

}
  • Related