2

I have a problem with acccessing a char ** in one of my struct.

    uint64_t id;
    struct timing timing;
    //command *command;
    uint32_t argc;
    char ** argv;
} taskR; 

i stock everything in my struct correctly but when it comes to reading it from a file i cant access the argv part whitout a "core dumped " alert (the other arguments work perfectly fine)

        taskR stp;
        uint64_t ip=stp.id;
        read(i,&stp,sizeof(struct task));
        struct timing ti;
        ti=stp.timing;//all good
        printf("%s",stp.argv[0]);//core dumped  

Happy new year everyone :) ty for the answer !!

imee
  • 31
  • 6
  • 1
    The answers to this question might help you: https://stackoverflow.com/q/2763438 – Artyer Jan 01 '22 at 23:49
  • Please, read [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) and edit your question to provide all declarations and definitions properly formatted, in a way we can compile and test, as with your snippets of code we are unable to do just syntax checking and little else. Thanks – Luis Colorado Jan 04 '22 at 10:51

1 Answers1

3

It will never work. You read only the value of the pointer argv but not the referenced array of pointers and strings assigned to it. Even if you read it they will reference other memory areas than the original ones when written.

You will need to serialize it and save all the underlying data. Then you will need to read it and reconstruct the structure.

example:

typedef struct
{
    unsigned id;
    unsigned timing;
    //command *command;
    unsigned argc;
    char ** argv;
} taskR; 

char *removeLastLF(char *str)
{
    char *wrk = str;
    if(str && str)
    {
        while(*(str + 1)) str++;
        if(*str == '\n') *str = 0;
    }
    return wrk;
}

int mywrite(FILE *fo, taskR *t)
{
    fprintf(fo, "%u,%u,%u\n", t -> id, t -> timing, t -> argc);
    for(unsigned i = 0; i < t -> argc; i ++)
    {
        fprintf(fo, "%s\n", t -> argv[i]);
    }
    return 0;
}

taskR *myread(FILE *fi)
{
    char buff[128];
    taskR *t = malloc(sizeof(*t));

    if(t)
    {
        fgets(buff, 128, fi);
        if(sscanf(buff, "%u,%u,%u\n", &t -> id, &t -> timing, &t -> argc) == 3)
        {
            t -> argv = malloc(t -> argc * sizeof(*t -> argv));
            for(unsigned i = 0; i < t -> argc; i ++)
            {
                fgets(buff, 128, fi);
                removeLastLF(buff);
                t -> argv[i] = malloc(sizeof(**t -> argv) * strlen(buff) + 1);
                strcpy(t -> argv[i], buff);
            }
        }
    }
    return t;
}

It requires much more error checking but I have skipped it for the sake of simplicity.

0___________
  • 60,014
  • 4
  • 34
  • 74
  • Thank you very much!! Would this be compatible with file descriptors since in our project we cannot use FILE type, so every writing and reading is done through ```write``` et ```read``` ? – imee Jan 02 '22 at 00:21
  • yes you will simple have more writing – 0___________ Jan 02 '22 at 00:24