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