【问题标题】:Realloc doesn't work in a while loopRealloc 在 while 循环中不起作用
【发布时间】:2015-08-02 14:22:52
【问题描述】:

我的 C 作业需要帮助。任务是编写一个程序,该程序接受长度未知的字符串输入。我还需要分隔单词,这就是我使用char** 的原因。当出现特殊单词时,程序停止输入。你可以在下面看到我的代码:

char **words=NULL;
 maxWords=1;
numberOfWords=0;
words=calloc(maxWords,sizeof(char **));
input=malloc(max*sizeof(char  *));

words[numberOfWords]=calloc(max,sizeof(char*));


while(stopValue){
    while((c=getchar())!='\n' && c!=' ' && c!=EOF){
        input[i++]=c;

        if(i==currentSize){
            currentSize=i+max;
            input=realloc(input,currentSize);
            words[numberOfWords]=realloc(words[numberOfWords],currentSize);
        }
    }
    input[i]='\0';
    if(strcmp(input,terminator)==0){
        break;
    }
    strcpy( words[numberOfWords],input);

    numberOfWords++;
    maxWords++;

    words=realloc(words,maxWords);
    words[numberOfWords]=calloc(max,sizeof(char*));
    currentSize=max;
    i=0;
    input=realloc(input,max);
 }

当我只有 2-3 个单词的输入时,效果很好。但是当有更多时它会失败。我认为问题出在words=realloc(words,maxWords); 这一行,但我不知道具体是什么。

有什么帮助吗?

【问题讨论】:

  • 为什么要重新分配单词而不是等待完整输入?为什么不只是 malloc 输入的副本?第一个输入分配在哪里?为什么在循环结束时重新分配它?
  • @RahulRaina 为什么realloc() 不能循环工作?
  • 对于maxWordsnumberOfWordscurrentSizemaxi、@987654331 等事物的类型和值,我高度怀疑我的 猜测 @ 等,会与您的实际运行值对齐。所以...发布MCVE
  • @Ôrel 他正在读取输入,没有要复制的字符串。
  • 在对calloc 的调用中使用maxWordsnumberOfWords 之后,您正在设置它们的值。那可能是错的。你也弄错了分配:指针不需要为自己分配空间,只为它指向的东西分配空间:Type *p = calloc(n, sizeof *p);

标签: c memory-leaks realloc


【解决方案1】:

calloc() 的第二个参数应该是指针指向的大小,即指向类型,而不是指针类型本身的大小。

例如,假设您想为 10 个int 分配空间,将结果分配给一个int *p,以下任何一种语法都是正确的并表现出定义的行为:

int *a = malloc(10 * sizeof(int));
int *b = calloc(10, sizeof(int));
int *c = realloc(NULL, 10*sizeof(int))
int *d = malloc(10 * sizeof *d);
int *e = calloc(10, sizeof *e);
int *f = realloc(NULL, 10 * sizeof *f);

指针对指针的行为没有什么不同。如果你想分配一个指向字符的序列,同样的语法适用:

char **a = malloc(10 * sizeof(char*));
char **b = calloc(10, sizeof(char*));
char **c = realloc(NULL, 10*sizeof(char*))
char **d = malloc(10 * sizeof *d);
char **e = calloc(10, sizeof *e);
char **f = realloc(NULL, 10 * sizeof *f);

请注意,除了指针类型本身(指针类型本身(第一个是指向int的指针,第二个是指向char的指针)。该语法利用了sizeof 运算符(它不是函数或宏;它是一个运算符)如何用于变量而不是类型

也就是说,您的代码中的words 是一个指向字符的指针。我应该使用类似的语法来分配适当的大小。以下任何一项都可以正常工作:

char **words = calloc(maxwords, sizeof(char*)); // right, uses specific type
char **words = calloc(maxwords, sizeof *words); // right, gets size from var type

两者都做同样的事情:分配一个正确对齐和调整大小的缓冲区以容纳 maxwords 数量的 char*,这正是您存储指向字符串的指针所需要的。

当你这样做时,这个问题再次被复制:

words[numberOfWords] = calloc(max, sizeof(char*)); // wrong

同样,wordschar**,所以 words[anything]char*,因此应该根据指向类型的大小分配分配:char。以下任一项都会这样做:

words[numberOfWords] = calloc(max, sizeof(char));   // right, or...
words[numberOfWords] = calloc(max, sizeof **words); // right

好吧,说了这么多,你怀疑这是错误的:

words = realloc(words, maxWords);

是有根据的。 realloc 函数将 字节数 作为第二个参数。您正在传递count of pointers,但不包括请求的字节数中每个指针的大小。使用前面描述的语法,可以这样做:

words = realloc(words, maxWords * sizeof *words);

words = realloc(words, maxWords * sizeof(char*));

两者都可以,现在包括每个指针的大小,从而计算出要请求的正确字节数。

祝你好运。

【讨论】:

  • words[numberOfWords-1] 这是一个错字。我更改了代码并没有注意到它。
  • 谢谢,我试试
  • words = realloc(words, maxWords * sizeof *words); 仍然是错误的,因为它在故障模式下错误地泄漏了内存(当realloc 返回NULL 时)。它的用途更像是:void *temp = realloc(words, maxWords * sizeof *words);if (temp == NULL) { /* XXX: perform error handling and return, break, exit or whatever */ }words = temp;
猜你喜欢
  • 2016-04-18
  • 1970-01-01
  • 2011-10-19
  • 1970-01-01
  • 2017-11-13
  • 1970-01-01
  • 1970-01-01
  • 2018-06-12
  • 1970-01-01
相关资源
最近更新 更多