The function is intended to form real numbers from an array of arrays (the program receives all data as a text file from which it must create an array of structures) using pointers to a part of the string. After debugging using the console, a memory problem was discovered. First, after the end of the line (the current_star variable), it contained some more garbage, and secondly, a memory overflow occurred. Please help me figure it out. Thank you in advance!

float *arrayCreate(char *str_data, float *bstars, int *k) { char *current_star = NULL, *cur_star_end; //current star size as a string int i = 0, sum = 0; bstars = NULL; cur_star_end = str_data; while (cur_star_end!=NULL) { cur_star_end = strchr(str_data, ' '); if (cur_star_end!=NULL) { current_star = (char*)realloc(current_star, sizeof(char)*(cur_star_end-str_data+1)); strncpy(current_star, str_data, cur_star_end-str_data); } else { current_star = (char*)realloc(current_star, sizeof(char)); strcpy(current_star, str_data); } if (strlen(current_star)!=1) { bstars = (float*)realloc(bstars, sizeof(float)*(i+1)); bstars[i] = atof(current_star); sum += bstars[i]; i++; if (cur_star_end!=NULL) str_data = cur_star_end+1; } } *k = i; free(current_star); current_star = NULL; free(str_data); str_data = NULL; return bstars; } 
  • char *current_star = malloc(1); This is for starters .. `bstars` also ... Not bad results for alok to check, you never know .. - NewView
  • @NewView, why so? We do it with realloc, we add an extra memory cell, and besides, the source line can be empty - Xiamera
  • It can not be empty, you first need to allocate memory, at least one byte, and then change its size. Both the string and the allocated memory are not the same. - NewView
  • @NewView: In no case! The realloc function perfectly knows how to work with a null pointer on an input. It is equivalent to malloc in this case. Using null at the start is an elegant and well-established pattern using realloc . Do not turn it into a terrible and useless malloc(1) . - AnT 6:51 pm
  • TC, can you give me all the code to check? - 0-Level UNIX Monk

1 answer 1

  1. An obvious and frequent error.

     current_star = (char*)realloc(current_star, sizeof(char)*(cur_star_end-str_data+1)); strncpy(current_star, str_data, cur_star_end-str_data); 

    followed immediately by

     if (strlen(current_star)!=1) 

    The strncpy function is not intended to safely copy strings and, in general, does not terminate the receive buffer with a '\0' character. The behavior of your program will depend on the garbage contained in the last byte allocated by your realloc .

    If you still want to use strncpy in this role, then do not forget to put '\0' at the end of the recipient string yourself. But, once again, the strncpy function is not intended for safe copying of strings and in the modern code has almost no practical applications.

     size_t length = cur_star_end - str_data; current_star = realloc(current_star, (length + 1) * sizeof *current_star); memcpy(current_star, str_data, length); current_star[length] = '\0'; 
  2. Here, in fact, the question arises as to why you are trying to "copy" the next substring from the input data into a separate string current_star . Why, if the translation into a number can be done right there in the input data itself ??? And no realloc are needed.

  3. Another mistake

     current_star = (char*)realloc(current_star, sizeof(char)); strcpy(current_star, str_data); 

    What is it? How did you decide that the tail of the str_data string str_data into a single char ?

     size_t length = strlen(str_data); current_star = realloc(current_star, (length + 1) * sizeof *current_star); strcpy(current_star, str_data); 
  4. What does checking mean

     if (strlen(current_star)!=1) 

    Do you have, the input can not come just a substring 3 ?

  5. The code is not designed for multiple spaces between numbers in the input. It is allowed?

  6. The functions of the ato... group are not intended for practical use. They exist only for compatibility with old code. Converting a string to a number in the standard C library is done by functions of the strto... group strto...

  7. Explicit casting of the type to (char *) on the result of the function of selecting a memory — hurts the eye.

  • "if (strlen (current_star)! = 1) Do you have that, just the number 3 can't come to the input?" - meant the last element of the array, I do not remember exactly. - Xiamera
  • "Explicit casting of the type to (char *) on the result of the memory allocation function - hurts the eye" - well, it seems to be how correct. At least we are so forced to do - Xiamera
  • @Xiamera: This check is done for all elements of the input string, and not only for the last one. - AnT
  • @Xiamera: For such "forcing" teachers should be sent to the army or for agricultural work. - AnT
  • I note that it is dangerous to assign the result realloc to the same pointer that is used in the function. Failure will return NULL and there will be a leak. - αλεχολυτ