使用 realloc() 时插入动态字符数组
Inserting into a dynamic character array while using realloc()
我非常想提高我的 C 编程技能,所以我开始了自己的自学计划,尝试读取文件并将它们的内容插入到不同的数据结构中。
在这里,我想专门使用一个动态分配的指针数组。我已经在另一个类似的程序中成功使用了 getc()
,但不是通过使用静态数组,所以我非常想在这里继续使用 getc()
函数。
所以在这个新的实现中,在这里,我只是试图将输入文件中的所有字符插入到我使用 malloc()
分配的数组中。一次读取一个字符后,我试图每次按一个字符的大小调整此指针数组的大小,以便在下一次迭代中为下一个字符留出空间。然后,之后,通过新的指针数组[逐个字符]迭代并简单地打印出所有内容。
但是,我收到了分段错误,所以也许我的做法有点不对?如果有任何反馈,我将不胜感激。
#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 );
}
}
在
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 ) ) );
}
第一次迭代会发生什么?
input_arrayPointer
是一个字节大
filled_elements
是 0
- 写入
input_arrayPointer
的第一个字节
filled_elements
递增
realloc
被调用 filled_elements
字节...即 1!!!没有数组大小增量!
- 第二个字符写入非法地址(动态分配区域外)
你只需要多分配一个字节
input_arrayPointer = ( char* ) realloc ( input_arrayPointer, ((filled_elements+1) * sizeof( char ) ) );
更好:始终检查 realloc
return 值。并使用临时指针,避免失败时丢失原指针。
realloc
什么时候失败?当它没有成功分配请求的大小时。在这种情况下,如 man page 中所述,NULL
将被 return 编辑并分配给 input_arrayPointer
。那不是你想要的。
类似的东西可以避免这个问题:
char *temp = realloc ( input_arrayPointer, ((filled_elements+1) * sizeof( char ) ) );
if (temp != NULL)
{
input_arrayPointer = temp;
}
注意: realloc
不保证扩展原始指针,因为它必须找到足够宽的连续内存范围以包含请求的大小。相反,它会找到新的内存区域并将指针的原始内容复制到那里(所有内容,如果 newSize > oldSize
;否则 newSize
字节)。
我非常想提高我的 C 编程技能,所以我开始了自己的自学计划,尝试读取文件并将它们的内容插入到不同的数据结构中。
在这里,我想专门使用一个动态分配的指针数组。我已经在另一个类似的程序中成功使用了 getc()
,但不是通过使用静态数组,所以我非常想在这里继续使用 getc()
函数。
所以在这个新的实现中,在这里,我只是试图将输入文件中的所有字符插入到我使用 malloc()
分配的数组中。一次读取一个字符后,我试图每次按一个字符的大小调整此指针数组的大小,以便在下一次迭代中为下一个字符留出空间。然后,之后,通过新的指针数组[逐个字符]迭代并简单地打印出所有内容。
但是,我收到了分段错误,所以也许我的做法有点不对?如果有任何反馈,我将不胜感激。
#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 );
}
}
在
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 ) ) );
}
第一次迭代会发生什么?
input_arrayPointer
是一个字节大filled_elements
是 0- 写入
input_arrayPointer
的第一个字节 filled_elements
递增realloc
被调用filled_elements
字节...即 1!!!没有数组大小增量!- 第二个字符写入非法地址(动态分配区域外)
你只需要多分配一个字节
input_arrayPointer = ( char* ) realloc ( input_arrayPointer, ((filled_elements+1) * sizeof( char ) ) );
更好:始终检查 realloc
return 值。并使用临时指针,避免失败时丢失原指针。
realloc
什么时候失败?当它没有成功分配请求的大小时。在这种情况下,如 man page 中所述,NULL
将被 return 编辑并分配给 input_arrayPointer
。那不是你想要的。
类似的东西可以避免这个问题:
char *temp = realloc ( input_arrayPointer, ((filled_elements+1) * sizeof( char ) ) );
if (temp != NULL)
{
input_arrayPointer = temp;
}
注意: realloc
不保证扩展原始指针,因为它必须找到足够宽的连续内存范围以包含请求的大小。相反,它会找到新的内存区域并将指针的原始内容复制到那里(所有内容,如果 newSize > oldSize
;否则 newSize
字节)。