1

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;
}
ty_1917
  • 151
  • 3
  • The above array is implicitly 10 chars wide, including the terminating nullchar. if you want something bigger either declare it explicitly as such or manually manage the memory with dynamic functions like `malloc`. A good book on C will elaborate considerably better, and as a bonus, have entire chapters on flow control using loops. – WhozCraig Mar 03 '22 at 09:15
  • Please see my edit. Is that correct? – ty_1917 Mar 03 '22 at 09:16
  • 1
    That'd certainly be one way to do it. Whether it fits your real need is another matter. Worth noting that will set the value of every member to the integer value `1`, which you should not confuse with the character literal `'1'`; they're not equivalent. Anyway, like I said, *get a good book*. C is not friendly to learn by trial and error, and very few of the so-called tutorial sites are worth the silicon they're printed on. And 'competitive' sites teach nothing but how to write really crappy code, so steer clear of those. – WhozCraig Mar 03 '22 at 09:26
  • This is after reading a book btw. – ty_1917 Mar 03 '22 at 09:31
  • Yes you can. If you want to initialise all of them to one, use `memset(data, 1, sizeof(data)`. I reckon you're using this to store large number of flags. – जलजनक Mar 03 '22 at 09:34
  • note that `memset` will only behave as you seem desired if your base array type is one char wide (e.g. char, unsigned char, int8_t, uint8_t). It will *not* work for types requiring multiple bytes for storage. Ex: `int` for, say, `int data[N];` on a 32bit platform will deliver a bunch of `int` values made up of `0x01010101`, i.e. 16843009, which will near-certainly not be the intent. – WhozCraig Mar 03 '22 at 09:49
  • Does this answer your question? [How to initialize all members of an array to the same value?](https://stackoverflow.com/questions/201101/how-to-initialize-all-members-of-an-array-to-the-same-value) – tstanisl Mar 03 '22 at 12:08

3 Answers3

3

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.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
0

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.

Lundin
  • 195,001
  • 40
  • 254
  • 396
0

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;

}
aulven
  • 521
  • 3
  • 14
  • For your last sentence about memset, how can you create data without typing and without for loop then? – ty_1917 Mar 03 '22 at 10:06
  • @ty_1917 I am not usre if I understood your question. The `memset` will replace only the `for` loop, not the definition of `char data ...`. The second argument of `memset` `1` in this case, is the data you are assigning in the `for` loop as `data[i] = 1`. – aulven Mar 03 '22 at 10:07
  • so you still use a for loop before using memset? – ty_1917 Mar 03 '22 at 10:10
  • @ty_1917 Please see the edit. – aulven Mar 03 '22 at 10:22
  • I still dont get it. U wrote sepearte answers. And the latest one its not clear where you create the data array? Where is data filled if there is no copy paste or for loop? – ty_1917 Mar 03 '22 at 11:58
  • For instance static char* data; In your code you treat data is already somewhere stored. Where do you and how do you create it(data array)? See my question again Im asking about creating data with for loop instead of copy paste a million characters – ty_1917 Mar 03 '22 at 12:02
  • @ty_1917 Fair enough, I believe the dynamic allocation part was confusing, and cluttered the answer as it was merely a further suggestion. I removed all related parts now. Hopefully it become clearer. – aulven Mar 03 '22 at 12:35