1

i have two structs

typedef enum { False = 0, True = 1 } bool;
//defenition of candy structure
typedef struct _Candy {
    char candy_name[16];
    bool vegan;
}Candy;
typedef struct _Child {
    char child_name[16];
    Candy *candy_of_child;
}Child;

now im trying to create an array of pointers that each one is Child type [*Child,*Child...] etc now i can initialize it i need to do it dynamically

the function that does in is:

int AllocateKidsArray(int NumOfKids, Child** ptr_to_child_arr) {
//=================================================
//"AllocateKidsArray" intializing an array of childrens
//Input:  1. int indicating the number of kids
//        2. pointer to an array of children
//Output: 1. return an int value {0}->Success {-1}->Failure
//        2. pointer to an empty initialized array of childerns
//=================================================
// array of length NumOfKids, consisting of Child pointers
Child **ptr_to_childs = malloc(NumOfKids * sizeof(Child*));
int i;
for (i = 0; i < NumOfKids; i++) {
    ptr_to_childs[i] = malloc(sizeof(Child));
    strncpy((*ptr_to_childs[i]).child_name, "", 16);
    (*ptr_to_childs)[i].candy_of_child = NULL;
}
*ptr_to_child_arr = *ptr_to_childs;
//for (i = 0; i < NumOfKids; i++) {
//  free(ptr_to_childs[i]);
//}
//free(ptr_to_childs);
return 0;
}

im calling it from the main in the following manner:

int main(int argc, char** argv) {
//=================================================
if (argc < 3) {
    printf("Incorrect number of arguments. Please invoke the program \n\t./program.exe < input.txt> <output.txt> \n");
    exit(1);
}
int i, lines, checker = 0;
Candy *test = NULL;
char* name_test = NULL;
char* candy_test = NULL;
char* line = "Tamar,Apple\n";
int* NumLinesFile = NULL;
Child *ArrayOfChild = NULL;
.
.
.
//GetNumLines check
printf("%s\n", argv[0]);
printf("%s\n", argv[1]);
printf("%s\n", argv[2]);
GetNumLines(argv[1], &NumLinesFile);
lines = *NumLinesFile;
*NumLinesFile = NULL;
printf("%d\n", lines);
//=================================================
//AllocateKidsArray check
//AllocateKidsArray(lines, &ArrayOfChild);
AllocateKidsArray(lines, &ArrayOfChild);
//ImportKidsArray check
ImportKidsArray(argv[1], lines, &ArrayOfChild);
for (i = 0; i < lines; i++) {
    //ArrayOfChild[i].candy_of_child = (Candy*) malloc(sizeof(Candy*));
    printf("%s,%s\n", ArrayOfChild[i].child_name, ArrayOfChild[i].candy_of_child->candy_name);
}
//=================================================

and im statistically get heap/buffer violation i suspect this function but i dont know what is wrong with it.

after the init of the array i pass it to another function that fills it in:

int ImportKidsArray(char* file_addr, int num_kids, Child** array_of_kids_to_fill) {
//=================================================
//"ImportKidsArray" reads the file and assign each valid line to cell in the array
//Input:  1. string to a location of a file
//        2. int indicating the number of kids
//        3. pointer to an array of children
//Output: 1. return an int value {0}->Success {-1}->Failure
//        2. pointer to an initialized array of childerns
//=================================================
FILE *fp;
char character;
char line[32];
int i = 0, j = 1, checker = 0, arr_count = 0;
char* TempChild = NULL;
char* TempCandy = NULL;
Child *arr = *array_of_kids_to_fill;

fp = fopen(file_addr, "r");
// Check if file exists
if (fp == NULL) {
    printf("Could not open file %s", file_addr);
    return -1;
}
while (!feof(fp)) {
    fgets(line, 32, fp);
    checker = ParseLine(line, &TempChild, &TempCandy);
    GetCandy(TempCandy, &(arr[arr_count].candy_of_child));
    strncpy((arr[arr_count]).child_name, TempChild, 16);
    arr_count++;

}
return 0;
}

please if anyone can help, it will save my life :)

David
  • 8,113
  • 2
  • 17
  • 36
  • 1
    The first thing I've noticed is that you're allocating the size of a child pointer instead of the size of a child... – theGleep Nov 13 '17 at 15:52
  • Do you need to use raw arrays and this stuff? C++ has very nice things that abstract those? And unless all those Kids will go out and kill you for not giving them candy, it is probably only a bad score. – Patrick Artner Nov 13 '17 at 15:52
  • what do you mean in raw arrays? – David Nov 13 '17 at 15:54
  • @chemist.: Post the content of those files..(input file and output file) – user2736738 Nov 13 '17 at 16:24

1 Answers1

0

You want to change to ArrayOfChild. Passing it's address from main().

Change it by appropriately de-referencing it.

*ptr_to_childs = malloc(NumOfKids * sizeof(Child));

Then do rest of the operation on *ptr_to_childs. That will retain the change that you made in the called function.

Also check the return value of malloc. And free(using free()) the memory dynamically allocated.

If you notice carefully you will see in the ArrayOfChild() function you are working with a local variable Child **ptr_to_childs. You certainly don't want that as that variable will not be alive when the function ends.

Also while (!feof(fp)) is not appropriate to use. Check this link for that.

Another thing is check the return value of char *fgets(char *str, int n, FILE *stream).

On success, the function returns the same str parameter. If the End-of-File is encountered and no characters have been read, the contents of str remain unchanged and a NULL is returned.

user2736738
  • 30,591
  • 5
  • 42
  • 56
  • where sholud i use free? in the allocatearray function or should i call a new function which will get the array that i work with inside the main and free evrey cell of it? – David Nov 13 '17 at 16:15
  • @chemist.: For example when you have processed this dynamicaly allocated memory or simply you dont need them at a point- call `free()` on them. – user2736738 Nov 13 '17 at 16:16
  • i see, and do i need to call only one free on the main pointer to the array, or should i go over every cell in the array? – David Nov 14 '17 at 06:28
  • @chemist.: Yes whatever you allocate...you need to `free()` it. The variable which contains the mallcoaed address call free() on it. – user2736738 Nov 14 '17 at 08:08