realloc无法正确复制值。

3

我试图读取一个大小未知的文本文件到一个数组中。我通过逐个字符地读入数组并在数组末尾达到时重新分配内存来实现这一目标。

从数组大小从16增加到32开始,realloc方法只复制前4个字符。

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


int main()
{
    int *text_arr = malloc(1*sizeof(int));
    text_arr[0] = '\0';
    int text_len=1;
    int i=0;
    FILE *fp;

    fp = fopen("1.txt", "r");
    
    while ((text_arr[i] = fgetc(fp)) != EOF) {
        /* increment i for next loop */
        i++;

        /* extend the array if needed */
        if (i >= text_len) {
            /* debug prints */
            printf("Text: ");
            for (int n=0; n<i; n++)
                printf("%c,", text_arr[n]);
            printf("\n\n");
            
            /* double array size */
            text_len *= 2;
            text_arr = (int*)realloc(text_arr, text_len);
        }
    }
    text_arr[i] = '\0';

    fclose(fp);
    
    return 0;
}

可能出了什么问题?


当 ((text_arr[i] = fgetc(fp)) != EOF) 时,fgetc() 返回一个 int。在比较之前将其转换为 char,会丢失 EOF 条件。 - wildplasser
@wildplasser 不是的,text_arr[i] 是一个 int 对象。 - Oka
3个回答

7

你正在处理sizeof(int)大小的对象,当你重新分配内存时,请确保将请求的字节数乘以这个大小。

realloc(text_arr, sizeof (int) * text_len);

3

realloc 接受以字节为单位的大小作为参数。然而,您正在传递以元素为单位的大小,这将因为您的元素是int类型而比实际小一倍(通常是4)。这意味着首次调整大小后,您实际上使数组变小了,然后继续在数组末尾写入数据。

在您的 malloc 行中加上 * sizeof(int) 就可以解决这个问题:

text_arr = (int*)realloc(text_arr, text_len * sizeof(int));

3
考虑第一次增加text_len的大小(从1到2)。您最初为text_arr分配了sizeof(int)字节。但是,当您调用realloc(text_arr, text_len)text_len为2时,您正在将数组从4个字节截断为2个字节(假设sizeof(int)为4)。
由于您正在将单个字符读入text_arr并引用它们,因此text_arr不应该是int*。相反,它应该是一个char*,并通过malloc(1*sizeof(char))进行分配(或者只需使用malloc(1),因为sizeof(char)被定义为1)。
另外,进行此更改后,当fgetc返回EOF时,您将无法将其存储在数组中。因此,您应将返回值存储在实际的int变量中,然后如果它不是EOF,则将其存储在数组中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接