Nathu
Nathu

Reputation: 551

What is the source of this 'realloc(): invalid next size' error

I've read the other questions of this type, but I still can't figure out why this error is occurring in my code.

Here is my code:

#include <stdio.h>
#include <stdlib.h>

typedef struct {                 
    int len;
    int str[0];
} bit_str;

bit_str * input(void);
void print_bitstr(bit_str * s);

int main(void)
{
    bit_str * s1 = input();
    print_bitstr(s1);

    return 0;
}

bit_str * input(void)
{
    bit_str *s = (bit_str *) malloc(sizeof(bit_str)); 
    int count = 0, bit;

    while ((bit = getchar()) != 'k'){
        s = (bit_str *) realloc(s, sizeof(*s) + sizeof(int));           
        s->str[count++] = bit - 48;
    }

    s->len = count;
    return s;
}

void print_bitstr(bit_str * s)
{
    for (int i = 0; i < s->len; i++)
        printf("%d ", s->str[i]);
    printf("\n");

    return;
}

This code is part of a program I was trying to add two bit strings together (as an exercise from a Data Structures book).

I've created a struct that will store the bits string and it's length. The struct is initialized using a malloc in the input function. It is reallocated every time a new bit is added. The bits are read using a getchar, and the end of a bitstring is demarcated by the letter 'k'.

When I compile the code, it works perfectly for exactly 6 bits. But if I try to input 7 bits, it crashes with following error:

> realloc(): invalid next size  

I've read the other posts with similar error, but I couldn't figure out why this error is occurring in my code here. I've made sure that when I reallocate, I use sizeof operator to get the size, instead of absolute values.

Can someone please help me figure out what I'm doing wrong here?

Upvotes: 1

Views: 115

Answers (1)

Jonathon Reinhart
Jonathon Reinhart

Reputation: 137398

sizeof(*s) is evaluated at compile-time; it has no knowledge of dynamic allocations such as malloc or realloc.

So even though you're attempting to dynamically add sizeof(int) bytes to the current allocation:

s = (bit_str *) realloc(s, sizeof(*s) + sizeof(int)); 

This always causes s to point to sizeof(bit_str) + sizeof(int) bytes.

Of course, after that no-op realloc, you proceed to write more bytes to the buffer, overrunning the buffer and resulting in undefined behavior.

Upvotes: 5

Related Questions