C语言 无法使realloc()工作


FILE *file;
file = fopen(argv[1], "r");
char *match = argv[2];
if (file == NULL) {
    printf("File does not existn");
    return EXIT_FAILURE;
}
int numWords = 0, memLimit = 20;
char** words = (char**) calloc(memLimit, sizeof(char));
printf("Allocated initial array of 20 character pointers.n");
char string[20];
while (fscanf(file, "%[a-zA-Z]%*[^a-zA-Z]", string) != EOF) {
    words[numWords] = malloc(strlen(string) + 1 * sizeof(char));
    strcpy(words[numWords], string);
    printf("Words: %sn", words[numWords]);
    numWords++;     /*keep track of indexes, to realloc*/ 
    if (numWords == memLimit) {
        memLimit = 2 * memLimit;
        words = (char**) realloc(words, memLimit * sizeof(char*));   /*Fails here*/
        printf("Reallocated array of %d character pointers.n", memLimit);
    }
}

代码应该打开并读取一个包含标点符号,空格等单词的文件,并存储在字符串中,但经过20次尝试后,它会抛出一个错误,我似乎无法让realloc()在这里工作,这是我期望的问题。数组被动态分配20个char指针,当达到限制时,它应该以双精度重新分配。我怎么才能避开这个问题呢?

注意两点。首先,不应该强制转换calloc/malloc/realloc的返回值。

第二,正如其他人在评论中指出的那样,第一个calloc语句使用了sizeof(char)而不是sizeof(char*)

words是指向指针的指针。其思想是分配一个指针数组。
下面的代码是错误的,因为它分配memLimit字符而不是memLimit指针。
这是主要问题

char** words = (char**) calloc(memLimit, sizeof(char)); // bad

所以使用一个简单的习惯用法:分配words所指向的memLimit组。它更容易编写、阅读和维护。

char** words = calloc(memLimit, sizeof *words);

避开while (scanf() != EOF)孔。回想一下,scanf()家族可以产生各种结果。它返回成功扫描字段的计数或EOF。这通常是至少三种选择中的一种。所以不要测试一个你不想要的结果,测试一个你想要的结果

// while (fscanf(file, "%[a-zA-Z]%*[^a-zA-Z]", string) != EOF) {
while (fscanf(file, "%[a-zA-Z]%*[^a-zA-Z]", string) == 1) {

上面的例子不一定都返回0,但是下面的例子很容易返回0。

int d;
while (fscanf(file, "%d", &d) == 1) {

@Enzo Ferber正确地建议使用"%s"。进一步建议遵循上述习惯用法,并将输入宽度限制为小于缓冲区大小的1。

char string[20];
while (fscanf(file, "%19s", string) == 1) {

建议养成检查分配结果的习惯。

    // better to use `size_t` rather than `int `for array sizes.
    size_t newLimit = 2u * memLimit;
    char** newptr = realloc(words, newLimit * sizeof *newptr);
    if (newptr == NULL) {
       puts("Out-of-memory");
       // Code still can use old `words` pointer of size `memLimit * sizeof *words`
       return -1;
    }
    memLimit = newLimit;
    words = newptr;
  }

错误信息

  • 不要强制转换malloc/calloc返回。没有必要。
  • 你的第一个sizeof是错误的。应该是sizeof(char*)
  • scanf()格式字符串。%s做得很好。

下面的代码为我工作(每行打印一个单词):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
    FILE *file;
    file = fopen(argv[1], "r");
    char *match = argv[2];
    if (file == NULL) {
        printf("File does not existn");
        return EXIT_FAILURE;
    }
    int numWords = 0, memLimit = 20;
    char **words = calloc(memLimit, sizeof(char*));
    printf("Allocated initial array of 20 character pointers.n");
    char string[20];
    while (fscanf(file, "%s", string) != EOF) {
        words[numWords] =
            malloc(strlen(string) + 1 * sizeof(char));
        strcpy(words[numWords], string);
        printf("Words: %sn", words[numWords]);
        numWords++; /*keep track of indexes, to realloc */
        if (numWords == memLimit) {
            memLimit = 2 * memLimit;
            words = realloc(words, memLimit * sizeof(char *));  
            printf
                ("Reallocated array of %d character pointers.n",
                 memLimit);
        }
    }
}

调用./realloc realloc.c

希望能有所帮助。

您的第一次分配是有问题的。分配20个字符,并将它们视为20个字符指针。您超出了分配的缓冲区并损坏了内存。

第二次分配失败,因为堆已损坏。

相关内容

  • 没有找到相关文章

最新更新