无法让realloc()工作

时间:2015-09-05 03:42:47

标签: c memory-management dynamic malloc realloc

FILE *file;
file = fopen(argv[1], "r");
char *match = argv[2];
if (file == NULL) {
    printf("File does not exist\n");
    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: %s\n", 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指针,当达到限制时,它应该重新分配为double。我怎么能绕过这个?

4 个答案:

答案 0 :(得分:3)

两个音符。首先,您不应该转换calloc / malloc / realloc的返回值。有关详细信息,请参阅this

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

答案 1 :(得分:2)

words是指向指针的指针。想法是分配一个指针数组 以下是错误的,因为它分配了memLimit个字符而不是memLimit个字符 这是主要问题

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

因此,请使用简单的习惯用法:分配memLimitwords点的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) { 。这通常是至少3个选项中的1个。因此,不要测试您不想要的一个结果,测试您想要的的结果。

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

以上示例可能并非每次返回0,但下面的内容很容易。

"%s"

@Enzo Ferber正确建议使用char string[20]; while (fscanf(file, "%19s", string) == 1) { 。进一步建议遵循上述习语,并将输入宽度限制为小于缓冲区大小的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;
  }

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

...
var html = "<div style='font-size: 2em; text-align: center;'>Some text here." +
    "<br /><br />" +
    "<ul>" +
       "<li>A bunch of text here</li>" +
       "<li>A bunch more text here</li>" +
    "</ul>" +
    "</div>";
iframeBody.innerHTML = html;
...

答案 2 :(得分:1)

错误

  • 不要投出 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 exist\n");
        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: %s\n", 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

调用

希望它有所帮助。

答案 3 :(得分:1)

你的第一个分配是问题。你分配20个字符并将它们视为20个字符指针。你超出了分配的缓冲区并破坏了你的记忆。

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