3

I've got a problem when i'm programming.

struct skills {
    int SnCrypt;
    char* Soutput;
    int Soptind;
    int Sdecrypt;
    int Sargc;
    char* Spassword;
    char *const Sargv[];
};

struct skills* initSkills(int nCrypt, char* password, char *const argv[], char* output, int optind, int decrypt, int argc) {
    struct skills* skill;
    skill->SnCrypt = nCrypt;
    skill->Spassword = password;
    skill->Sargv = argv;
    skill->Soutput = output;
    skill->Soptind = optind;
    skill->Sdecrypt = decrypt;
    skill->Sargc = argc;

    return skill;
}

And gcc tell me

invalid use of flexible array member

for the line skill->Sargv = argv;.

I don't understand how could I point the value pointed by char *const argv[] by an other pointer? I'm aware that I surely must malloc the skill->Sargv pointer but how? Like this (char const*)malloc(sizeof(argv[]))?

Chilledrat
  • 2,593
  • 3
  • 28
  • 38
user3380144
  • 31
  • 1
  • 1
  • 2
  • The code doesn't look like C++ and certainly not C#, maybe it's C? – anatolyg Mar 04 '14 at 17:54
  • @anatolyg Yes, flexible arrays is a C feature. –  Mar 04 '14 at 17:55
  • You don't need to restate `struct` when declaring a `struct` variable (if this really is C++), and you need to allocate memory for it (otherwise your application will crash). – crashmstr Mar 04 '14 at 17:55

1 Answers1

7

The answer below is in C, which appears to be more appropriate than C++ in the context of this question.

You're basically not supposed to declare an array with an unknown number of entries (AKA "flexible array"). The only way to do so - exactly as you did - is by declaring it as the last field in the structure.

It sort of indicates that the size of the entire structure is unknown.

And being as such, you cannot statically instantiate this structure:

struct skills x; // will generate a compilation error

Instead, you can only instantiate it dynamically. For example, here is an instance of this structure with its Sargv array large enough to accommodate 5 elements:

struct skills* x = malloc(sizeof(struct skills)+5*sizeof(char*));

Having said all that, there are two options for you to fix your code:

Option #1 - assuming that you are calling function initSkills with the argv of function main (which resides in memory throughout the entire lifetime of the program), you might as well declare:

struct skills
{
    ...
    char** const Sargv; // instead of 'char* const Sargv[]'
};

Option #2 - allocate the struct skills instance with its Sargv array large enough to accommodate argc elements, and then copy each element from the argv array into the Sargv array:

int i;
struct skills* skill = malloc(sizeof(struct skills)+argc*sizeof(char*));
...
for (i=0; i<argc; i++)
{
    skill->Sargv[i] = malloc(strlen(argv[i])+1);
    strcpy(skill->Sargv[i],argv[i]);
}
return skill;

Please note that you have an additional (unrelated) fix to apply in your code:

Change this:

skill->Spassword = password;

To this:

skill->Spassword = malloc(strlen(password)+1);
strcpy(skill->Spassword,password);
barak manos
  • 29,648
  • 10
  • 62
  • 114