【问题标题】:Multiple error messages while working with pointer and malloc in c在 c 中使用指针和 malloc 时出现多个错误消息
【发布时间】:2014-11-17 11:25:04
【问题描述】:

我对 C 语言还是很陌生,并且在我的代码中收到了多个错误消息,如果有人可以向我解释这些错误消息,那就太好了。

我的代码:

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

int main()
{
  char newINPUT;

  char* INPUT = (char*)malloc(1 * sizeof(char));



  while((INPUT = getchar()) =! EOF)
    char* newINPUT = (char*)realloc(INPUT, 2* sizeof(INPUT));
    if(newINPUT =! NULL)
    {
      INPUT = newINPUT;
    }
    else
    {
      free(INPUT);
      printf("Out of memory!");
    }

    return 0;

}

这应该做的是:它应该分配一些内存并读取您键入的内容。当没有分配的内存时,它应该重新分配两倍于以前分配的内存。

错误信息: 警告第 13 行(带有 while 的那一行):赋值使指针从整数不进行强制转换(默认启用) 错误第 13 行:需要左值作为赋值的左操作数 错误第 14 行:“char”之前的预期表达式 第 17 行警告:与第 13 行相同。

如果有人能向我解释一下就好了。谢谢!


编辑:感谢到目前为止的所有答案!他们确实帮助我理解了 malloc 和 realloc。我昨天尝试了另一个自己的版本,但我不确定分配的内存是否正常工作,因为我无法用足够大的输入对其进行测试。这对 realloc 和加倍有效(语法上)吗?

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

int main()
{

  int *READ; //input
  READ = malloc(sizeof(int));


  while ((*READ = getchar()) != EOF)
  {
    if (READ) //if read not null so memory is enough
    {
      putchar(*READ);
    }
    else
    {
      int x;
      int* extendedREAD = realloc(READ, (x*2));//expression for "double as much as before"????

      if (extendedREAD = NULL) // looking if there s enough memory
      {
        printf("Error, not enough memory!");
      }
      x = x * 2;
    }
  }



  return 0;
}




/*
Zeichen einlesen - checken ob eof, wenn nein, dann speicher ausreichend? nein dann vergräßern, sonst zeichen dazuschreiben, dann wieder vonvorne)
*/

谢谢!

【问题讨论】:

  • 1) char newINPUT; :未使用此变量。还有重复的名字。
  • 2) INPUT = getchar()INPUT 的类型是 char *getchar() 的返回值类型为int
  • 3) 2* sizeof(INPUT) : sizeof(INPUT)sizeof(char*)。它总是相同的值。
  • 4) =! 应该是 !=
  • 5) while((INPUT = getchar()) =! EOF) 需要 { }

标签: c pointers


【解决方案1】:

这里有很多问题...

int main()
{
  char newINPUT;

  char* INPUT = (char*)malloc(1 * sizeof(char));

Don't cast the result of a call to malloc(); 这是不必要的,可能会导致意想不到的问题。

  while((INPUT = getchar()) =! EOF)

这里有两个问题。首先,a =! b 表示“将a 设置为b 的逻辑补码”。您可能想使用 a != b 形式的东西("a 不等于 b")。其次,getchar() 返回一个int 值。如果您尝试将返回值存储在char 容器中,您可能会发现它永远不会等于EOF

    char* newINPUT = (char*)realloc(INPUT, 2* sizeof(INPUT));

在这里,您将 newINPUT 重新声明为 char* 指针。您之前将其声明为char newINPUT。这会导致编译错误。

    if(newINPUT =! NULL)

您在此处将newINPUT 设置为NULL 的逻辑补码。我想你的意思是if (newINPUT != NULL)。您可以直接使用 if (newINPUT)

(关于内存泄漏的废话已删除——我的错!)

总体而言,您的程序逻辑存在缺陷,因为您试图为输入的每个字符增加一倍分配的内存。所以即使你解决了上述问题,在输入大约 32 个字符后,你也会耗尽内存。


建议重写:

以下代码将输入缓冲区的当前大小存储在size 中,并将输入字符串的长度存储在nchars 中。两者都初始化为零。缓冲区位置本身 (char *input) 可以初始化为NULL,因为使用空指针调用realloc() 等效于调用malloc()。这意味着我们可以从代码中消除一个系统调用。

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

int main() {
  char *input=NULL, *new_input;
  int c, size=0, nchars=0;

  while (1) {
    if (size==nchars) {
      size = size*2 + (size==0);  /* (size==0) is 1 if size==0, zero othewise */
      if (!(new_input = realloc(input,size))) {
        puts("Out of memory");
        free(input);
        return 1;
      }
      input = new_input;
      printf("Buffer reallocated; new size is %d byte(s)\n",size);
    }
    if ((c=getchar())==EOF) {
      input[nchars] = '\0';  /* Terminate the input string */
      break;
    }
    input[nchars++] = c;
  }

  printf("Buffer size:   %d\n"
         "String length: %d\n"
         "Input was:     %s\n",size,nchars,input);
  free(input);
  return 0;
}

【讨论】:

  • 感谢您的冗长回答,非常感谢。我还有一些问题。关于内存泄漏 - 为什么它不再有任何指向?我真的不明白那部分。
  • 总体而言——我不想每次添加新字符时都将分配的内存加倍,我确实希望只有当输入在 malloc 中没有可用内存时才加倍,就像它加倍一样从 8 到 16,它只会在 9、10、11、12、13、14、15 之后翻倍 - 现在。你有如何写下来的提示吗?
  • 如果我写 while 像 " while((INPUT = getchar()) != EOF && INPUT != 0) 它只会重新分配更多的内存,如果它不能更安全地进入输入,意思是如果没有可用空间了。对吗?
  • @Yíu 对不起,我错了。没有内存泄漏 :-) 如果您只想在必要时将内存分配加倍,则需要存储缓冲区的当前大小及其包含的字符数。我添加了一些代码来向您展示我将如何做到这一点。
  • 非常感谢!我喜欢消除一个系统调用而不变得更复杂的想法。我可以请你尽快解释一下这条线吗? “如果(!(new_input = realloc(输入,大小)))”。我真的不明白它的作用。
【解决方案2】:

修改示例

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

int main(void){
    int ch;
    char* INPUT = (char*)malloc(1 * sizeof(char));
    int input_buf_size = 1;
    int input_count = 0;

    while((ch = getchar()) != EOF){
        INPUT[input_count] = ch;
        input_count += 1;
        if(input_count == input_buf_size){
            char *newINPUT = (char*)realloc(INPUT, input_buf_size *= 2);
            if(newINPUT != NULL){
                INPUT = newINPUT;
            } else {
                free(INPUT);
                printf("Out of memory!");
                exit(EXIT_FAILURE);
            }
        }
    }
    INPUT[input_count] = '\0';
    puts(INPUT);
    free(INPUT);
    return 0;
}

【讨论】:

  • 您的解决方案非常好且易于理解。不过我真的不明白你为什么需要 INPUT[input_count] = ch; .这是否与在 while 循环中编写 put(INPUT) 相同?我从来没有见过这样写的。
  • 我还编辑了我的问题并发布了我在阅读您的答案之前所做的尝试,您能看一下吗?
  • @Yíu *READ = getchar() : 这只是使用缓冲区的开头。
  • @Yíu 新添加的代码也包含了问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
  • 2014-04-24
  • 1970-01-01
相关资源
最近更新 更多