简体   繁体   中英

Issue with for loop in C when using struct

I did the following code to read values from a text file. Text file looks like this.(in code it's named as annotation.txt )

299.jpg
480
640
3
dog
124
234
380
290
hand
789
456
234
123
wire
900
567
456
234

Here's the code.

#include <stdio.h>
#include <stdlib.h>

typedef struct object
{
    char obj_name[20];
    int x_min;
    int y_min;
    int x_max;
    int y_max;

} Object;

typedef struct annotation
{
    char img_name[20];
    int width;
    int height;
    int num_obj;

    Object objects[];
} Annotation;

void readAnnotation(char *fileName, Annotation *annot);

int main()
{
    Annotation annot;
    readAnnotation("annotation.txt", &annot);

    printf("%s\n", annot.img_name);
    printf("%d\n", annot.width);
    printf("%d\n", annot.height);
    printf("%d\n", annot.num_obj);
    printf("0th object name for the 1st time %s\n", annot.objects[0].obj_name); // here it can be seen as 'dog'

    for (int i = 0; i < 3; i++)
    {
        printf("%s\n", annot.objects[i].obj_name); // oth one disappear
        printf("%d\n", annot.objects[i].x_min);
        printf("%d\n", annot.objects[i].y_min);
        printf("%d\n", annot.objects[i].x_max);
        printf("%d\n", annot.objects[i].y_max);
    };
    printf("0th object name for the 2nd time %s\n", annot.objects[0].obj_name); //here it disappear
};

void readAnnotation(char *fileName, Annotation *annot)
{
    FILE *fp;
    fp = fopen(fileName, "r");
    if (fp == NULL)
    {
        printf("\nError: Cannot open file");
        exit(1);
    };

    fscanf(fp, "%s", annot->img_name);
    fscanf(fp, "%d", &(annot->width));
    fscanf(fp, "%d", &(annot->height));
    fscanf(fp, "%d", &(annot->num_obj));

    for (int i = 0; i < annot->num_obj; i++)
    {
        fscanf(fp, "%s", annot->objects[i].obj_name);
        fscanf(fp, "%d", &(annot->objects[i].x_min));
        fscanf(fp, "%d", &(annot->objects[i].y_min));
        fscanf(fp, "%d", &(annot->objects[i].x_max));
        fscanf(fp, "%d", &(annot->objects[i].y_max));
    };

    fclose(fp);
};

When I run the code, inside the for loop written in main() function makes the annot.objects[0].obj_name to disappear. When I check it before the for loop the value can be seen as 'dog'. But within the for loop and after the for loop, that value disappears. Can anyone tell me the issue with my code and give me a proper answer to solve this.

objects is never initialized. You're just writing to junk memory. Object objects[]; does not create an array, it actually creates a pointer to an array , and you're required to allocate memory for it. If you don't you're just exercising an uninitialized pointer and your program may or may not work or might crash. It's undefined behaviour .

Normally this is declared as Objects* objects to make it clear it's really a pointer and to remember to allocate. Arrays and pointers can often be interchanged, so no other code changes are required.

Before your readAnnotation loop:

annot->objects = calloc(annot->num_obj, sizeof(Object));

regarding:

typedef struct annotation
{
    char img_name[20];
    int width;
    int height;
    int num_obj;

    Object objects[];
} Annotation;

The above only allocates room for the first 4 fields then a pointer, however, No room is allocated for an array 0f object Suggest: either use malloc() and/or realloc() to allocate memory for the instances of Object

Otherwise any reference to objects[x] is undefined behavior can can lead to a seg fault event

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM