Home > Net >  Realloc fails without any particular reason
Realloc fails without any particular reason

Time:04-24

I am trying to solve a "suppose to be" a simple C question.

Q: Receive "infinite" input by user using int pointer until EOF received using malloc and realloc.

I defined a int pointer like this:

int *inputBuffer = NULL;

and initialized it using this method:

    /* #define BUFFER_SIZE 8  - already defined at top of code, posted here for more info */    
/* Creates buffer by using malloc - 
            if succeded returns true, otherwise false */
        int createBuffer(int **inputBuffer)
        {
            *inputBuffer = (int*) calloc(BUFFER_SIZE, sizeof(char)); /* Allocate memory to get input from user */
            if(*inputBuffer == NULL)    
                return FALSE;
            return TRUE;
        }

by calling createBuffer(&inputBuffer) so far so good, memory is allocated successfully. before starting to receive characters from user I defined the following properties:

int totalCharacters = 0;
int bufferExtendsCounter = 1;
int character;

Next step is to receive characters inputs from user like this:

   /* #define MEMORY_SAFE_GAP 4  - already defined at top of code, posted here for more info */
  while((character = getchar()) != EOF && inputBuffer != NULL)
  {
        /* Check if reallocate needs to be called since almost maxed out buffer */
        if(totalCharacters - MEMORY_SAFE_GAP > (BUFFER_SIZE * bufferExtendsCounter))
        {
            /* Add 1 to extends buffer times */
            bufferExtendsCounter =1;
            if(!extendBuffer(&inputBuffer, totalCharacters))
                printf("\nFailed to allocate more memory.");
        }       

        /* Initialize buffer with character, this is safe since there is a memory safe gap */
        inputBuffer[totalCharacters] = character;

        totalCharacters  ;
  }

extend buffer looks like this:

/* Extends buffer size by using realloc 
    if succeded returns true, otherwise false */
int extendBuffer(int **inputBuffer, int minimumBufferSize)
{
    /* Check how many times buffer needs to be multiple (at least) */
    int multipleBufferNumber = (minimumBufferSize / BUFFER_SIZE)   1;
    int newBufferSize = BUFFER_SIZE * multipleBufferNumber * sizeof(char);
    while(newBufferSize < minimumBufferSize)
    {
        multipleBufferNumber =1;
        newBufferSize = BUFFER_SIZE * multipleBufferNumber * sizeof(char);
    }
    /* Reallocate memory for next chunck of data */
    *inputBuffer = realloc(*inputBuffer, newBufferSize);
    /* Check if memory successfully allocated */
    if(*inputBuffer == NULL)
        return FALSE;
    return TRUE;
}

It looks like I extend the buffer size enough for more input by user, but still gets error:

corrupted size vs. prev_size: 0x08f86010 ***

Example input:

TestProgramTest (Pressed Enter after last 't')
(DebugPrint: Received 13 characters)
(DebugPrint: Reallocating to size 16)
*** Error in `./test': corrupted size vs. prev_size: 0x08f86010 ***

EDIT (Due to lack of code parts): The following part is right after while loop:

    inputBuffer[totalCharacters] = '\0';
    printf("\nInput by user:\n");
/* #define LINE_LENGTH 5  - already defined at top of code, posted here for more info */
    printBuffer(inputBuffer, LINE_LENGTH, totalCharacters);
    /* free memory */
    free(inputBuffer);

and printBuffer looks like:

/* Prints the buffer data to pretty output */
void printBuffer(int *inputBuffer, int lineLength, int totalCharacters)
{
    int i;
    for(i = 0; i < totalCharacters; i  )
    {
        /* Print each char value */
        printf("%c", inputBuffer[i]);
        /* Check if got to line limit, if so enter new line */
        if((i 1) % lineLength == 0)
            printf("\n");
    }
}

Second edit: Changed all int pointer parts to char pointer. Full code looks like:

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

#define LINE_LENGTH 5
#define BUFFER_SIZE 8
#define TRUE 1
#define FALSE 0
#define MEMORY_SAFE_GAP 4

int createBuffer(char **inputBuffer);
int extendBuffer(char **inputBuffer, int minimumBufferSize);
void printBuffer(char *inputBuffer, int lineLength, int totalCharacters);

int main(void)
{
    char *inputBuffer = NULL;
    if(!createBuffer(&inputBuffer))
    {
        printf("Memory cannot be allocated, program will exit now.");
        exit(-1);
    }
    int totalCharacters = 0;
    int bufferExtendsCounter = 1;
    char character;

    printf("Please enter a string:\n");
    /* Loop till EOF received */ 
    while((character = getchar()) != EOF && inputBuffer != NULL)
    {
        /* Check if reallocate needs to be called since almost maxed out buffer */
        if(totalCharacters - MEMORY_SAFE_GAP > (BUFFER_SIZE * bufferExtendsCounter))
        {
            /* Add 1 to extends buffer times */
            bufferExtendsCounter =1;
            if(!extendBuffer(&inputBuffer, totalCharacters))
                printf("\nFailed to allocate more memory.");
        }       

        /* Initialize buffer with character, this is safe since there is a memory safe gap */
        inputBuffer[totalCharacters] = character;

        totalCharacters  ;
    }
    inputBuffer[totalCharacters] = '\0';      
    printBuffer(inputBuffer, LINE_LENGTH, totalCharacters);
    /* free memory */
    free(inputBuffer);
    return 0;
}
/* Creates buffer by using malloc
    if succeded returns true, otherwise false */
int createBuffer(char **inputBuffer)
{
    /* Allocate memory to get input from user */
    *inputBuffer = (char*) calloc(BUFFER_SIZE, sizeof(char)); 
    if(*inputBuffer == NULL)    
        return FALSE;
    return TRUE;
}

/* Extends buffer size by using realloc 
    if succeded returns true, otherwise false */
int extendBuffer(char **inputBuffer, int minimumBufferSize)
{
    /* Check how many times buffer needs to be multiple (at least) */
    int multipleBufferNumber = (minimumBufferSize / BUFFER_SIZE)   1;
    int newBufferSize = BUFFER_SIZE * multipleBufferNumber * sizeof(char);
    while(newBufferSize < minimumBufferSize)
    {
        multipleBufferNumber =1;
        newBufferSize = BUFFER_SIZE * multipleBufferNumber * sizeof(char);
    }
    /* Reallocate memory for next chunck of data */
    *inputBuffer = realloc(*inputBuffer, newBufferSize);
    /* Check if memory successfully allocated */
    if(*inputBuffer == NULL)
        return FALSE;
    return TRUE;
}

/* Prints the buffer data to pretty output */
void printBuffer(char *inputBuffer, int lineLength, int totalCharacters)
{
    printf("Printing buffer\n");
    int i;
    for(i = 0; i < totalCharacters; i  )
    {
        /* Print each char value */
        printf("%c", inputBuffer[i]);
        /* Check if got to line limit, if so enter new line */
        if((i 1) % lineLength == 0)
            printf("\n");
    }
}

Any help would be great!

Thanks in advance.

CodePudding user response:

Right here

  *inputBuffer = (int*) calloc(BUFFER_SIZE, sizeof(char)); 

You reserve space for 8 chars but try to store 8 ints in it

Why isnt inputBuffer just a char*? since thats what you are storing

Now you have fixed that - look at this

if (totalCharacters  - MEMORY_SAFE_GAP > (BUFFER_SIZE * bufferExtendsCounter))

I do not know what the intention of the 'MEMORY_SAFE_GAP' is but its wrong

Look at what happens when I input character number 8

  if(8 - 4 > 8 * 1)

is false, so you do not extend the buffer.

This 'SAFE-GAP ensure that you always run off the end, your code no longer crashes if you just have

 if (totalCharacters  >= (BUFFER_SIZE * bufferExtendsCounter))

output is still a little garbled but you can probably fix that. I input 1234567890 and got

Please enter a string:
1234567890
^Z
Printing buffer
12345
678═0
  • Related