context: https://stackoverflow.com/a/34528438/15603477
The original post left some realloc code unfinished in read_solidfunction, inside if(strcmp("endfacet", line) == 0) {}. trying to finish this part. but failed.
Almost the same as original post code.
Problem:
In if((*sol)->nfacets == (*sol)->maxfacets) {} code block, I need realloc a struct inner struct.
if I set FACETS = 3 then a single solid struct pointer can only hold 3 facet pointer. Now I want to resize/reallocated to make it can hold more facets pointers.
/*
https://stackoverflow.com/questions/34522831/scanf-stops-working-abruptly/34528438#34528438
gcc \
-Wpointer-arith  -Werror=vla -Wendif-labels \
-Wimplicit-fallthrough -Wmissing-format-attribute  \
-Wcast-function-type -Wshadow=compatible-local \
-Wformat-security -Wno-format-truncation -Wno-stringop-truncation \
array_struct96.c  &&./a.out dat/solid.txt
valgrind ./a.out  dat/solid.txt
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#include<errno.h>
#include<math.h>
/* constants - num dimensions, initial facets
 * allocated within each solid, and the max
 * chars per-line for fgets to read
 */
enum{NDIM = 3, FACETS = 3, MAXC= 256};
/* facets struct - declared as pointer member of 
 * struct solid allowing additional allocation to
 * hold as many normal/vertexes as required.
 */
typedef struct facet{
    double normal[NDIM];
    double vertex[NDIM][NDIM];
}facet;
/* struct solid holds the solid's name, 
 * a pointer to an array of stuct facet, 
 * the number of facets containing data, and 
 * the maximum presently allocated.
 */ 
typedef struct solid{
    char *name;
    facet *facets;
    size_t nfacets;
    size_t maxfacets;
}solid;
/* function prototypes */
solid *create_solid();
solid *read_solid(solid **sol, FILE *fp);
void print_solid(solid *sol);
void free_solid(solid *sol);
double xstrtod(char *str, char **ep);
/* simple allocate/initialize function
 * return must be assigned to pointer
 */
solid *create_solid()
{
    size_t i;
    solid *sol = calloc(1,sizeof *sol);
    sol->facets = calloc(FACETS, sizeof *(sol->facets));
    sol->nfacets = 0;
    sol->maxfacets = FACETS;
    for(i = 0; i < FACETS; i++){
        memset((sol->facets)[i].normal, 0,NDIM * sizeof(double));
        memset((sol->facets)[i].vertex, 0,NDIM * NDIM * sizeof(double));
    }
    return sol;
}
/*  simple print of normals & vertexes to stdout    */
void print_solid(solid *sol)
{
    if(!sol){
        fprintf(stderr,"printf_solid() error: invalid parameter 'sol'.\n");
        return;
    }
    size_t i,j;
    printf("Normal and vertexes for solid: %s\n", sol->name);
    printf("Total size of faces=%ld\n", sol->nfacets);
    for(i = 0; i < 5; i++){
        printf("record %ld: ", i+1);
        printf(
            "\nnormal[%3zu]:%10.4f\t%10.4f\t%10.4f\n",i
            ,sol->facets[i].normal[0]
            ,sol->facets[i].normal[1]
            ,sol->facets[i].normal[2]
        );
        for(j = 0; j < NDIM; j++)
            printf("vertex[%3zu]:%10.4f\t%10.4f\t%10.4f\n"
                ,j
                ,sol->facets[i].vertex[j][0]
                ,sol->facets[i].vertex[j][1]
                ,sol->facets[i].vertex[j][2]
            );
    }
}
void free_solid(solid *sol)
{
    if(sol->name) free(sol->name);
    if(sol->facets) free(sol->facets);
    if(sol) free(sol);
}
/* string to double with error checking. */
double xstrtod(char *str, char **ep)
{
    errno = 0;
    double val = strtod(str,ep);
    /* Check for various possible errors */
    if((errno == ERANGE  && (val == HUGE_VAL || val == HUGE_VALL)) ||
        (errno != 0 && val == 0)){
            perror("strtod");
            exit(EXIT_FAILURE);
    }
    if(ep && *ep == str){
        fprintf(stderr,"No double were found.\n");
        exit(EXIT_FAILURE);
    }
    return val;    
}
int main (int argc, char **argv) {
    solid *sol = NULL;  /* pointer to hold values */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
    if (!fp) {  /* validate file open */
        fprintf (stderr, "error: file open failed '%s'\n", argv[1]);
        return 1;
    }
    if (read_solid (&sol, fp)) {    /* read data from file  */
        print_solid (sol);          /* print data read      */
        free_solid (sol);           /* free all memory      */
    }
    if (fp != stdin) fclose (fp);   /* close if not stdin   */
    return 0;
}
/* read_solid takes the poiner address for a struct solid,
 * and will read all normal and vertexes into the struct,
 * updating 'nfacets' with the number of facets for which
 * there is data, and will validate each read and conversion
 * of values from string to double. retuns filled struct on
 * success, NULL otherwise
 */
solid *read_solid(solid **sol, FILE *fp)
{
    char line[MAXC] = {0};  /*  temporary line buffer */
    size_t idx = 0, vidx = 0;   /* line & vertex indexes */
    if(!*sol) *sol = create_solid();     /* allocate & initialize struct */
    
    while(fgets(line,MAXC,fp))   /* read each line in file */
    {
        size_t len = 0;
        char *p, *ep;
        p = ep = line;
        len = strlen(line);  /* get length & remove '\n' */
        if(line[len - 1] == '\n')
            line[--len] = 0;
        if(!(ep = strchr(line,' ')))    /* test if space in line */
        {   /* if endfacet, update nfacets */
            if(strcmp("endfacet", line) == 0)
            {
                (*sol)->nfacets++;
                if((*sol)->nfacets == (*sol)->maxfacets)
                {
                    fprintf(stderr,"read_solid() warning: limit readed\n");
                    printf("(*sol)->nfacets=%ld\n", (*sol)->nfacets);
                    // sol->facets = calloc(FACETS, sizeof *(sol->facets));
                    printf("2 * ((*sol)->maxfacets:%ld\n",2 * (*sol)->maxfacets);
                    void *tmp = realloc ( (*sol)->facets, 2 * ( (*sol)->maxfacets ) * sizeof *(*sol)->facets);
                        if (!tmp) { /* if realloc fails, original pointer still valid */
                            perror ("realloc-sales");   /* throw error */
                            return (*sol);              /* return current pointer      */ 
                        }                               /* (don't exit or return NULL) */
                        (*sol)->facets = tmp;    /* assign reallocated block to (*sol)->facets  */
                        /* (optional) zero newly allocated memory */
                        // memset ((*sol)->facets + (*sol)->nfacets, 0, ((*sol)->maxfacets) * sizeof *((*sol)->facets));
                    (*sol)->maxfacets *= 2;  /* update (*sol)->maxfacets to new size */
                    printf("this part do called\n");
                    break;
                }
            }
            goto processed;
        }
        if(strncmp("solid",line,ep - p) == 0)
        {
            (*sol)->name = strdup(ep + 1);
            goto processed;
        }else if(strncmp("facet",line, ep - p) == 0)
        {
            size_t i;
            while(*ep &&(*ep < '0' || *ep > '9')) ep++; /* skip no digit value */
            if(!*ep){
                fprintf(stderr,"read_solid() error: facet normal no values\n");
                return NULL;
            }
            p = ep;
            for(i = 0; i < NDIM; i++){   /* convert to double & validate */
                /* for which sol index.
                for a specific index of sol
                then assign double to normal.*/
                (*sol)->facets[(*sol)->nfacets].normal[i] = xstrtod(p,&ep);
                p = ep;
            }
            goto processed;
        }else if(strncmp("vertex", line, ep - p) == 0)
        { /* read vertex values */
            size_t i;
            p = ep + 1;
            for(i = 0; i< NDIM; i++){/* convert to double & validate */
                (*sol)->facets[(*sol)->nfacets].vertex[vidx][i] = xstrtod(p,&ep);
                p = ep;
            }
            vidx = vidx < 2 ? vidx + 1 : 0; /* update/reset vertex index */
            goto processed;
        }else if(strncmp("outer",line,ep - p) == 0){ /* skip line begin with outer*/
            goto processed;
        }else if(strncmp("endsolid",line, ep - p) == 0){ /* skip line begin with endsolid*/
            goto processed;
        }else{
            fprintf(stderr,"read_solid() warning: invalid line at '%3zu'\n",idx);
        }
    processed:
        idx++;
    }
    
    if(!(*sol)->nfacets){
        fprintf(stderr,"read_solid() error: no data read.\n");
        free_solid(*sol);
        return NULL;
    }
    printf("idx=%ld\n", idx);
    return *sol;
}
In print_sold function. for(i = 0; i < 5; i++) 0,1,2 is ok. but 3,4 print
record 4:
normal[  3]:    0.0000      0.0000          0.0000
vertex[  0]:    0.0000      0.0000          0.0000
vertex[  1]:    0.0000      0.0000          0.0000
vertex[  2]:    0.0000      0.0000          0.0000
record 5:
normal[  4]:    0.0000      0.0000          0.0000
vertex[  0]:    0.0000      0.0000          0.0000
vertex[  1]:    0.0000      0.0000          0.0000
vertex[  2]:    0.0000      0.0000          0.0000
I modified dat/solid.txt file, so all print should be no zero value. Which mean the realloc part failed.
 
    