简体   繁体   中英

What's wrong when I allocate and free memory for a nested struct with union inside

I use Linux and programming with its C compiler tools and the IDE Geany.

I try to learn how to use structs with union inside, and allocate mem for them dynamically. I have a dynamicaly alocated array with my nested structs;

struct SellItem {
    char  title[50];
    char description[500];
    int price;
    int nr_of_img;
    char ** image_files;//array of strings
};

struct ParagraphItem{
    char * text;
};

union ContentItem{//one of the following only
    struct SellItem s_item;
    struct ParagraphItem p_item;
};

struct Content{
    int type;//1=sellitem 2=paragraph
    union ContentItem c_item;
};

In main:

struct Content * content; // The array to be

int content_count=0; // To show array size

I have filled up with two items for testing, starting with the "image files";

char ** img_files;

img_files = malloc(sizeof(char*) * 2);//two strings
img_files[0] = malloc(25);
img_files[1] = malloc(25);

strcpy(img_files[0], "img1.jpg");
strcpy(img_files[1], "img2.jpg");

struct SellItem item1 = {.title = "Pants", .description="Brown", .price=200, .image_files = img_files, .nr_of_img = 2};
struct SellItem item2 = {.title = "Shirt", .description="White", .price=100, .nr_of_img = 0};

content = malloc(sizeof(struct Content) * 2);
content[0].type=1;
content[0].c_item.s_item = item1;
content[1].type=1;
content[1].c_item.s_item = item2;

content_count = 2;

This seems to work.

When I try to add a new item I use the function:

void increase(struct Content** content, int *nr_of_content){
//I send in content_count as 2:nd param

*content = realloc(*content, (*nr_of_content+1) * sizeof(struct Content));
(*nr_of_content)++;
}

I set it with

content[content_count].type = 1;
strcpy(content[content_count].c_item.s_item.title, "Test");
strcpy(content[content_count].c_item.s_item.description, "Beskrivning");
content[content_count].c_item.s_item.price = 100;
content[content_count].c_item.s_item.nr_of_img = 0;

It can be accessed and printed on screen with another print function that has the "top-declaration"

void print_1_content(struct Content);

When I close the program I want to free the memory;

if(content_count > 0)
{
   printf("Ska fria minnne\n");
   for(int i=0;i<content_count;i++)
   {
      printf("I content nummer %d\n", i);
      if(content[i].type==1)
      {
          printf("%i är typ 1\n", i);
          if(content[i].c_item.s_item.nr_of_img>0)
          {
              printf("Har bilder\n");
              for(int j=0;j<content[i].c_item.s_item.nr_of_img;j++)
              {
                  printf("Ska fria bild nr %d\n", j);
                  free(content[i].c_item.s_item.image_files[j]);
                  printf("Friade en img minne\n");
              }
          }
      }
      else if(content[i].type==2)
      {
         printf("%i är typ 2\n", i);
         free(content[i].c_item.p_item.text);
      }
   }
   free(content);
   content_count=0;
}

I get the error message

*** Error in `./short_v': double free or corruption (!prev): 0x0000560b6727cf90 ***

Aborted (core dumped)

It comes when reaching the third item (cell).

This is one of two errors, and the other one comes when I want to print all content on screen.

Your use of content_count is wrong:

strcpy(content[content_count].....

but content_count indexes beyond the array. Hence undefined behavior.

Use:

strcpy(content[content_count-1]....

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