C - realloc error: corrupted size vs prev_size
size
needs updating when inputch == '\n'
.
char *tmp = realloc(str, sizeof(char) * length + 1 /* or no +1 */);
can shrink the allocation. which makes a later if (length == size)
invalid (the true allocation size is smaller) and so str[length++] = inputch;
lost memory access protection. Update size
to fix that hole.
+1
not needed - it simply hid the problem as the + 1
did not shrink the allocation as much.
char *tmp = realloc(str, sizeof(char) * length);
if (tmp == NULL) {
exit(0);
} else {
str = tmp;
}
size = length; // add
Concerning sizeof(char)*
code. The idea of scaling by the size of the target type is good, yet with char
it is not important as it is always 1. @Lee Daniel Crocker
If code wants to reflect that the type of the target may change, do not use size(the_type)
, use sizeof(*the_pointer)
. Easier to code, review and maintain.
// Don't even need to code the type `str` points to
tmp = realloc(str, sizeof *str * length);
rhoward
Updated on January 24, 2020Comments
-
rhoward over 4 years
Could someone please explain the error?
I was getting the error until, on a whim, I changed the line from:char *tmp = realloc(str, sizeof(char)*length); // to added 1 char *tmp = realloc(str, sizeof(char) * length + 1);
I thought that multiplying
sizeof(char)
by length would reallocate a new memory area ofsize=sizeof(char)*length
. I'm not understanding why adding 1 fixes the problem.void edit_print(char *inputStr, size_t space_size) { size_t ch_position = 0; size_t space_column_count = 0; size_t num_spaces_left = 0; while ((inputStr[ch_position] != '\0')) { if ((inputStr[ch_position] == '\t') && (space_size !=0)) { num_spaces_left = (space_size-(space_column_count % space_size)); if (ch_position == 0 || !(num_spaces_left)) { for (size_t i=1; i <= space_size; i++) { putchar(' '); space_column_count++; } ch_position++; } else { for (size_t i=1; i <= num_spaces_left; i++) { putchar(' '); space_column_count++; } ch_position++; } } else { putchar(inputStr[ch_position++]); space_column_count++; } } printf("\n"); } int main(int argc, char *argv[]) { size_t space_size_arg = 3; int inputch; size_t length = 0; size_t size = 10; char *str = realloc(NULL, sizeof(char) * size); printf("Enter stuff\n"); while ((inputch = getchar()) != EOF) { if (inputch == '\n') { str[length++] = '\0'; //changed line below char *tmp = realloc(str, sizeof(char) * length + 1); if (tmp == NULL) { exit(0); } else { str = tmp; } edit_print(str, space_size_arg); length = 0; } else { str[length++] = inputch; if (length == size) { char *tmp = realloc(str, sizeof(char) * (size += 20)); if (tmp == NULL) { exit(0); } else { str = tmp; } } } } free(str); return 0; }
EDIT: the error message I original got was the one in the heading of this post. After making the changes suggested by chux, the error is "realloc(): invalid next size: *hexnumber**"
-
user4581301 over 6 yearsRecommend letting us in on "the error" Could be very helpful in figuring out what went wrong.
-
Igor Tandetnik over 6 yearsMy guess:
edit_print
contains a buffer overrun error. You masked this bug by giving it some extra room to overrun into. -
chux - Reinstate Monica over 6 yearsOT: This does not explain the error, yet
sizeof(char) * length + 1
is semantically incorrect. Thesizeof()
should multiple by the sum oflength + 1
. But since, in this case,sizeof(char)==1
--> no problem. -
Lee Daniel Crocker over 6 yearsFirst of all, "sizeof(char)" is defined to be 1, so is irrelevant and superfluous everywhere. Then, the only code that seems to do anything with all this memory you're allocating is edit_print(), which you're not showing us.
-
rhoward over 6 years@LeeDanielCrocker I added the function
-
rhoward over 6 years@user4581301 the error is in the header. Thats all im getting.
-
chux - Reinstate Monica over 6 years@rhoward207 Prior to each
... = realloc(ptr, sz);
, addfprintf(stderr, "%d %p %zu\n", __LINE__, (void*)ptr, sz);
and report the last output before code dies. -
rhoward over 6 years@chux what is sz in the arguments?
-
chux - Reinstate Monica over 6 yearsIn
realloc(NULL, sizeof(char) * size);
,sz
issizeof(char) * size
, Inrealloc(str, sizeof(char) * length + 1);
,sz
issizeof(char) * length + 1
. Inrealloc(str, sizeof(char) * (size += 20));
sz
issizeof(char) * (size + 20));
(not+=
). -
chux - Reinstate Monica over 6 yearsGeneral comment: A weak design attribute is testing the size after setting an element of the array. A better approach would test space availability first before
str[length++] = inputch;
and beforestr[length++] = '\0';
-
chux - Reinstate Monica over 6 yearsMinor:
if ((!*end) && num > 0)
--->if (options[2] != end && (!*end) && num > 0)
-
chux - Reinstate Monica over 6 yearsInstead of including
process_options()
code. A MCVE would have usedsize_t space_size_arg = 3;
- assuming that still fails. GTG -
pm100 over 6 yearsarent you allocated the buffer
str
for the next string on each loop. Are they all the same size? First time you have str = 10 bytes, then you count chars and realloc str to the size you just read. But that buffer is used fro the next string
-
-
rhoward over 6 yearsunfortunately your suggestion does not fix the error. I will edit my post to include what I am seeing. I also added edit_print. thank for the info about sizeof(type).
-
David C. Rankin over 6 yearsPlease provide a A Minimal, Complete, and Verifiable example for further help.
-
rhoward over 6 years@chux after adding fprintf, last few lines: ##### ####### ####### ###### # ####### ###### 100 0x55da9f4416a0 41 # # # # # # # # # # # # # 100 0x55da9f4416a0 41 # # # # # # # # # # # # 100 0x55da9f4416a0 44 *** Error in `./project1': corrupted size vs. prev_size: 0x000055da9f4416c0 *** Aborted (core dumped)
-
rhoward over 6 yearsfprintf(stderr, "%d %p %zu\n", LINE, (void*)str, sizeof(char)*length+1); @chux
-
chux - Reinstate Monica over 6 years@rhoward207 Notice that the problem occurs on the first non-blank line shorter than prior ones. Certainly the issue is in shrinking the allocation. The 100 is suspicious as no line is longer than about 75 characters - hmmmm.