2

我非常想赶上我的 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 );
    }
}
4

1 回答 1

0

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 ) ) );
}

第一次迭代会发生什么?

  1. input_arrayPointer是一个字节大
  2. filled_elements是 0
  3. 的第一个字节input_arrayPointer被写入
  4. filled_elements递增
  5. realloc被称为 filled_elements字节......那是1!没有数组大小增量!
  6. 第二个字符被写入非法地址(动态分配区域外)

你只需要再分配一个字节

input_arrayPointer = ( char* ) realloc ( input_arrayPointer, ((filled_elements+1) * sizeof( char ) ) );

更好:总是检查realloc返回值。并使用临时指针避免丢失原始指针以防万一失败。
什么时候realloc失败?当它没有成功分配请求的大小时。在这种情况下,如手册页中所述,NULL将返回并分配给input_arrayPointer. 那不是你想要的。
这样的事情可以避免这个问题:

char *temp = realloc ( input_arrayPointer, ((filled_elements+1) * sizeof( char ) ) );
if (temp != NULL)
{
    input_arrayPointer = temp;
}

注意: realloc不保证扩展原始指针,因为它必须找到足够宽的连续内存范围以包含请求的大小。相反,它会找到新的内存区域并将指针的原始内容复制到那里(所有内容,如果newSize > oldSizenewSize否则为字节)。

于 2020-06-08T20:48:03.270 回答