简体   繁体   中英

Dynamic reallocation an array of structures with malloc and realloc

I am really having a difficult time trying to create an array of structures using malloc and realloc. I have posted mostly the entire code base, or at least the relevant information pertaining to the question below.

struct _section {
    char *sectName;
    int start_addr;
    int end_addr;
    char *bytes;
};

struct _section *get_exe_sections(struct _section *exe_sect, Elf *elf, GElf_Ehdr *ehdr, GElf_Shdr *shdr, Elf_Data *data) { 
    exe_sect->sectName = elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name);
    exe_sect->start_addr = shdr->sh_addr;
    exe_sect->end_addr = shdr->sh_addr + shdr->sh_size;
    exe_sect->bytes = (unsigned char *)data->d_buf;

    return exe_sect;  
}

int main(int argc, char *argv[]) {
    Elf *elf;
    int fd;

    //process input file
    int sections_count = count_sections(elf);
    GElf_Ehdr ehdr_mem;
    GElf_Ehdr *ehdr = gelf_getehdr(elf, &ehdr_mem);

    struct _section *exe_sect = (struct _section *)malloc(sizeof(struct _section));
    for(int cnt = 0; cnt < sections_count; cnt++) {
        Elf_Scn *scn = elf_getscn(elf, (size_t)cnt);
        GElf_Shdr shdr_mem;
        GElf_Shdr *shdr = gelf_getshdr(scn, &shdr_mem);
        Elf_Data *data = elf_getdata(scn, NULL);

        if(ehdr == NULL || shdr == NULL)
            exit(1);

        if(strcmp(header_name(SECT_TYPE, GELF_ST_TYPE(shdr->sh_type)), "PROGBITS") == 0) {
            if(strcmp(flag_name(SECT_FLAGS, shdr->sh_flags), "ALLOC & EXECUTE") == 0 || \
                strcmp(flag_name(SECT_FLAGS, shdr->sh_flags), "EXECUTE") == 0) {

                exe_sect = get_exe_sections(exe_sect, elf, ehdr, shdr, data);
                struct _section *nxt_sect = (struct _section *)realloc(exe_sect, 2*sizeof(*exe_sect));
                if(nxt_sect != NULL)
                    exe_sect = nxt_sect;
            }
        }
    }
    return 0;
}

What I am having trouble with is creating an array of structures dynamically and using malloc and realloc to resize the structure to fit more data into it. If I were to place a handful of print statements are the bottom of main the output will give me the last data that was input to the structure. How would I go about accessing individual entries that were made during each call to get_exe_section ? From prior posts and other resources I thought this would work, but I cannot create an array in this manner. Any form of help would be great. Thanks.

You could add another element in your struct that points to the next section. This way you could create a linked list

struct _section {
    char *sectName;
    int start_addr;
    int end_addr;
    char *bytes;
    struct _section *next; // pointer to next section
};

You could use another Struct to point to the head of your list.

and then instead of using realloc . you could just do

exe_sect->next = (struct _section *)malloc(sizeof(struct _section));

Here is how I would change the main function :

int main(int argc, char *argv[]) {
    Elf *elf;
    int fd;

    //process input file
    int sections_count = count_sections(elf);
    GElf_Ehdr ehdr_mem;
    GElf_Ehdr *ehdr = gelf_getehdr(elf, &ehdr_mem);

    struct _section *exe_sect = (struct _section *)malloc(sizeof(struct _section));

    for(int cnt = 0; cnt < sections_count; cnt++) {
        Elf_Scn *scn = elf_getscn(elf, (size_t)cnt);
        GElf_Shdr shdr_mem;
        GElf_Shdr *shdr = gelf_getshdr(scn, &shdr_mem);
        Elf_Data *data = elf_getdata(scn, NULL);

        if(ehdr == NULL || shdr == NULL)
            exit(1);

        if(strcmp(header_name(SECT_TYPE, GELF_ST_TYPE(shdr->sh_type)), "PROGBITS") == 0) {
            if(strcmp(flag_name(SECT_FLAGS, shdr->sh_flags), "ALLOC & EXECUTE") == 0 || \
                strcmp(flag_name(SECT_FLAGS, shdr->sh_flags), "EXECUTE") == 0) {

                exe_sect = get_exe_sections(exe_sect, elf, ehdr, shdr, data);
                exe_sect->next = (struct _section *)malloc(sizeof(struct _section));

                if(exe_sect->next != NULL)
                    exe_sect = exe_sect->next;
            }
        }
    }
    return 0;

PS : To access all the individual entries, add another struct that consists of a pointer to the head of the list, and a variable that keeps count.

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