2
votes

I keep passing in and returning the dirs_later_array. When I get to "new_size=..." in the else block, I end up with new_size of 2 the second time around. So far so good. But when I do a realloc

dirs_later_array = realloc(dirs_later_array,
new_size * sizeof(struct dirs_later*));

the sizeof remains at 4, the size of the pointer, for dirs_later_array. I'm able to succesfully store at dirs_later_array[1] but that value keeps getting overwritten the next time I go into the function.

struct dirs_later** add_struct(const char *findme, struct dirent *dptr,
        struct stat *this_lstat, char *relative_path, const char *type_str,
        struct dirs_later **dirs_later_array) {

    struct dirs_later *new_dir = malloc(sizeof(struct dirs_later));
    check_realloc_dirs_error(new_dir);

    if (strcmp(dptr->d_name, ".")) { //Dir and not same directory
        //Copy the relative path to the struct
        char *relative_path2;
        relative_path2 = malloc(strlen(relative_path) + 1);
        check_realloc_error(relative_path2);
        strcpy(relative_path2, relative_path);

        //if (strlen(relative_path) > 0)
        //    relative_path2[strlen(relative_path) - 1] = '\0';

        if (NULL != new_dir) {
            new_dir->findme = findme;
            new_dir->dptr = dptr;
            new_dir->st_mode = this_lstat->st_mode;
            new_dir->relative_path = relative_path2;
            new_dir->type_str = type_str;
        }
        int new_size = 0;
        /*
         //Check if this is the first element in the struct
         if (sizeof(dirs_later_array) / sizeof(struct dirs_later*) == 1) {
         new_size = 1;
         }
         */
        if (dirs_later_array == NULL) {
            dirs_later_array = malloc(sizeof(struct dirs_later*)); //Store the directory structures or process later
            check_realloc_arr_error(*dirs_later_array);
            new_size = 1;
        } else {

            //Add directories to directories array
            new_size = (((sizeof(dirs_later_array) + sizeof(struct dirs_later*)))/sizeof(struct dirs_later*));
            //printf("new size: %d",new_size);
        }
        dirs_later_array = realloc(dirs_later_array,
                new_size * sizeof(struct dirs_later*));
        check_realloc_arr_error(dirs_later_array);
        dirs_later_array[new_size - 1] = new_dir;
    }
    return dirs_later_array;
}



2
reallocdoes not resize anything it justs allocates dynamic memory specified as an parameter and assigns it to your pointer.Alok Save
@Als But it does! It does resize!Mr Lister
@Als - Any also ensures that the original contents remain unchanged (in as far as to the new amount of space)Ed Heal
It is a fundamental C and C++ rule that something's size does not depend on the values it contains. Were this not the case, how would know what size to pass to malloc? You'd need the value to know the size, but if you had some place to put the value, you probably wouldn't need to call malloc.David Schwartz

2 Answers

11
votes

Operator sizeof is a compile time feature and it only checks the static size of an expression. So for pointer it only returns the size of that pointer which is 4 on your platform. sizeof does not measure the size of a dynamically allocated data. There is no standard feature in C to get the size of dynamically allocated data.

4
votes

Your sizeof(struct dirs_later*) should be changed to sizeof(struct dirs_later) - as before!

Also the sizeof is a compile time feature. You need a structure like this to hold the size

struct my_dirs
   struct dirs_later *dirs;
   int size;
};

Initialise it like this

struct my_dirs directories;
directories.size = 0;
directories.dirs = NULL;

Then to add (note realloc can take NULL as a parameter

directories.dirs = realloc(directories.dirs,
                           (++directories.size) * sizeof(struct dirs_later));

This would also simplify your code.