1

I'd like to fill array of MyStruct with same value. How can it be done in fastest and simplest way? I'm operating on rather low-level methods, like memset or memcpy.

edit: std::fill_n indeed complies and works fine. But it's C++ way. How can it be done in pure C?

struct MyStruct
{
    int a;
    int b;
};

void foo()
{
    MyStruct abc;
    abc.a = 123;
    abc.b = 321;

    MyStruct arr[100];
    // fill 100 MyStruct's with copy of abc
    std::fill_n(arr, 100, abc); // working C++ way

    // or maybe loop of memcpy? But is it efficient?
    for (int i = 0; i < 100; i++)
        memcpy(arr[i],abc,sizeof(MyStruct));
}
Greg Witczak
  • 1,634
  • 4
  • 27
  • 56
  • 2
    What error did you get with `std::fill_n`? – juanchopanza Oct 20 '13 at 18:39
  • 1
    `std::fill_n(arr, 100, abc);` [compiles](http://ideone.com/1LBfQz) – P0W Oct 20 '13 at 18:43
  • 2
    When you post a question like this to SO you'll get to a useful answer fastest, if not solve the problem yourself, but posting a working [sscce](http://sscce.org/) and all relevant output - in this case posting the compiler error would probably have revealed the problem was that you didn't `#include `. For your sscce, use something like ideone.com to put together an example independent of your build system. – kfsone Oct 20 '13 at 18:56
  • @P0W : it compiles indeed. My bad. I've modified question. – Greg Witczak Oct 20 '13 at 19:33
  • You can only get opinions on the fastest way for this (As there are a whole bunch of things we do not know from the question). The only way to find the fastest is to try them and time it. – Martin York Oct 20 '13 at 19:34

6 Answers6

8

Be careful to type names of your types correctly (it's case sensitive) and don't forget the semicolon after the definition of your struct, apart from these, your program should compile with no problems:

#include <iostream>
#include <algorithm>

struct MyStruct
{
    int a;
    int b;
}; // <------------- HERE

int main() {
    MyStruct abc;
    abc.a = 123;
    abc.b = 321;

    MyStruct arr[100];
    std::fill_n(arr, 100, abc);

    std::cout << arr[99].b;
}

outputs 321.


"How can it be done in fastest and simplest way?"

The simplest way would probably be using std::vector and its appropriate constructor instead:

#include <vector>

void foo()
{
    MyStruct abc;
    abc.a = 123;
    abc.b = 321;

    std::vector<MyStruct> vec(100, abc);
    ...
}
LihO
  • 41,190
  • 11
  • 99
  • 167
  • _Simplest_ but not sure if its _fastest_ ? – P0W Oct 20 '13 at 18:45
  • @P0W: Fair enough. Edited. – LihO Oct 20 '13 at 18:50
  • 2
    @POW: I bet it is: [std::vector is so much slower than plain arrays?](http://stackoverflow.com/a/3664349/14065). Ps vector is not slower. Personally I would not even declare the extra variable `abc`. Either add a constructor so you can use like this: `std::vector vec(100, MyStruct(123,321));` or use C++11 initializer list `std::vector vec(100, {123,321});` – Martin York Oct 20 '13 at 19:35
  • It's working fine, thanks! My problem is solved, but question is still open - is there a pure C way of doing that? – Greg Witczak Oct 20 '13 at 19:38
  • @gogowitczak: Unfortunately I don't know C its a completely different language. – Martin York Oct 20 '13 at 19:42
2
for(int i = 0; i < 100; i++)
{
    arr[i] = abc;
}

Fastest and cleanest. The optimizer will most likely work it's magic too.

Tri-Edge AI
  • 330
  • 2
  • 15
2

The following should work in C

MyStruct arr[100] = {
   {123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},
   {123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},
   {123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},
   {123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},
   {123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},
   {123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},
   {123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},
   {123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},
   {123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},
   {123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321},{123,321}};
Martin York
  • 257,169
  • 86
  • 333
  • 562
0

Not pure C, but GCC allows you to do it quite nicely:

MyStruct arr[100] = { [ 0 ... 99 ] = { .a = 123, .b = 321 } };

If you need pure C, I'd follow Tri-Edge Al's answer.

Community
  • 1
  • 1
ugoren
  • 16,023
  • 3
  • 35
  • 65
0

My guess in the C99 would be below code:

#include <stdio.h>

typedef struct MyStruct
{
    int a ;
    int b ;
} MyStruct_t;

const MyStruct_t abc = 
{
    .a = 0,
    .b = 321, 
};

void main(void)
{
    int i = 0 ;

    MyStruct_t arr[100] = {0} ;

    for(i=0 ;i <sizeof(arr)/sizeof(arr[0]);i++)
    {
        arr[i] = abc ;
    }
}

In my opinion this is cleanest, safest solution.

Lazureus
  • 462
  • 4
  • 19
0

here is how i did it in c:

#include <stdio.h>

struct MyStruct{
    int a;
    int b;
};

/*fill the array with a specified element.*/
void fillArray(void* array, int arraySize, void* elem, int elemSize){
    for(int i = 0; i < arraySize; i++){
        memcpy((char*)array + i * elemSize, elem, elemSize);
    }
}

int main(){
    struct MyStruct array[10];
    struct MyStruct elem;
    elem.a = 123;
    elem.b = 321;
    fillArray(array, 10, &elem, sizeof(struct MyStruct));
    for(int i = 0; i < 10; i++){
        printf("%i, %i\n", array[i].a, array[i].b);
    }
    return 0;
}

I create a function called fillArray which uses memcpy to copy a specified element into each slot of the array. I now just put the corresponding element into the function parameter and print it out.

silver takana
  • 138
  • 12