I am very much wanting to catch up on my C programming skills, so I have started my own self-training program, attempting to reading files and inserting their contents into different data structures.
Here, I am wanting to use specifically a dynamically-allocated pointer array. I have already used getc() successfully in another similar program, but instead through the use of a static array, so I would very much like to continue using the getc() function here.
So in this new implementation, here, I am just trying to insert all characters from an input file into an array, which I allocated using malloc(). After one character is read at a time, I am trying to resize this pointer array by the size of one character each time so that there is room for the next character on the next iteration. Then, afterwards, iterate [character by character] through the new pointer array and simply print out all the contents.
However, I am receiving segmentation faults, so maybe I am going about this a little wrong? I would appreciate very much any feedback.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void main( int argc, char *argv[] )
{
FILE *filePointer;
int c, i;
char *input_arrayPointer;
input_arrayPointer = ( char* ) calloc ( 1, sizeof( char ) );
printf("%p\n", input_arrayPointer);
int filled_elements = 0;
filePointer = fopen( argv[1], "r" );
if ( argc > 2 )
{
printf( "\nIncorrect usage, please say...\nRunProgram *filename*\n\n" );
exit( 1 );
}
if ( filePointer != NULL )
{
while ( ( c = getc( filePointer ) ) != EOF )
{
// filled_elements, to start, is 0
*( input_arrayPointer + filled_elements ) = c;
filled_elements++;
input_arrayPointer = ( char* ) realloc ( input_arrayPointer, (filled_elements * sizeof( char ) ) );
}
}
fclose( filePointer );
for ( i = 0; i < filled_elements; i++, input_arrayPointer++ )
{
printf("%c", *( input_arrayPointer + filled_elements );
}
}
In
What happens at the very first iteration?
input_arrayPointeris one byte bigfilled_elementsis 0input_arrayPointeris writtenfilled_elementsis incrementedreallocis called forfilled_elementsbytes... that is 1!!! No array size increment!You just need to allocate one byte more
Better: always check
reallocreturn value. And use a temporary pointer to avoid the loss of the original pointer in case it fails.When does
reallocfail? When it doesn't succeed in allocating the requested size. In that case, as described in man page,NULLwill be returned and assigned toinput_arrayPointer. That's not what you want.Something like that will avoid the issue:
Note:
reallocdoes not guarantee to extend the original pointer, as it has to find a contiguous memory range wide enough to contain the requested size. Instead, it finds the new memory area and copies there the original contents of the pointer (all of it, ifnewSize > oldSize;newSizebytes otherwise).