【问题标题】:Dynamic memory allocation with int array使用 int 数组进行动态内存分配
【发布时间】:2013-12-18 06:49:47
【问题描述】:

我有一个任务,我必须接受用户的输入。我不能使用链表,只能使用数组,所以我的计划是:

  1. 分配一些内存。

  2. 如果我们需要重新分配,意味着我达到了分配的单元格数:

    1. 尝试重新分配。如果成功,那就太好了。

    2. 如果我们不能重新分配,那么打印输入、释放内存和重新分配。

我无法真正决定告诉我如何到达分配的内存末尾的命令,这就是我需要你帮助的原因。我写道:

if (i==(MAX_CHARS_INPUT-1))

但我不确定。

代码:

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

#define MAX_CHARS_INPUT 200
#define D_SIZE 2

void printWithMalloc(){
    int charSize=1; 
    int *ptr=malloc(MAX_CHARS_INPUT*sizeof(charSize));

    int i=0, j=0, c;
    printf("please enter a string\n");

    while ((c=getchar())!=EOF && c!='\n')
    {
        ptr[i++]=c;
        if (i==(MAX_CHARS_INPUT-1)) /*if we need to realloc*/
        {
            int *temp=realloc(ptr,D_SIZE*MAX_CHARS_INPUT*sizeof(charSize));
            if (temp==NULL) /*realloc failed*/
            {
                printf("you wrote:\n");
                while(j<=i)
                    putchar(ptr[j++]);

                free(ptr);
                ptr=(int*)malloc(MAX_CHARS_INPUT*sizeof(charSize));
            }
            else
                ptr=temp;
        }
    }
}

int main(){
    printWithMalloc();
    return 0;
}

谢谢!

【问题讨论】:

  • sizeof(charSize) 会给你一个 int 的大小,因为 harSize 是一个 int。相反,只需执行sizeof(char)
  • 更好的是,完全省略它,因为sizeof(char) 的定义是 1。
  • 您可能需要重新考虑使用额外的 2 个字节进行 realloc,因为它不是很有效,如果您的环境不是嵌入式环境(每个字节都很重要),只需添加一个 100 字节的块,如果空间不够,它会减少重新分配的数量。有一个变量来跟踪缓冲区大小,当你重新分配时增加它。
  • ptr 是ints 的缓冲区,而不是chars。 sizeof(charSize) 可能看起来很困惑,但它(也许是无意的)是正确的。请改用sizeof *ptr,因为这将始终有效,尤其是如果您更改了ptr 的类型。
  • @Kninnug,charSize 有意将每个单元格初始化为 1 位,即使它是 int。也许我应该更改变量的名称?谢谢大家的回答。

标签: c memory-management malloc free realloc


【解决方案1】:

问题确实出在你的条件上:

if (i==(MAX_CHARS_INPUT-1))

这有效,但仅限于您第一次达到此限制。当您realloc 时,您的缓冲区会变大,但您不会检查是否用完 空间。所以想象一下我输入了 500 个字符。当读取第 199 个字符时,缓冲区被重新分配为 400 个字符大。但是,i仅在第 199 个字符处检查,因此当到达第 400 个字符时,它将用完缓冲区。

第二个问题是,当你重新分配缓冲区时,它只会增长到 400 个字符 (D_SIZE * MAX_CHARS_INPUT) 并且不会更大。

第三个问题是当你重新malloc 时(即当realloc 失败时)你没有重置i 所以它会立即写到缓冲区的末尾。

正如现在已删除的答案中所建议的那样。跟踪您的缓冲区大小:

size_t buffSize = MAX_CHARS_INPUT;

重新分配时,先更新buffSize,然后将其用作realloc 的参数:

buffSize *= D_SIZE; // double the buffer-size
temp = realloc(ptr, buffSize * sizeof(*temp)); // using sizeof *temp is less confusing and less error-prone

当然:也更新您的状况:

if(i == buffSize - 1)

当你重新malloc重置i和buffSize时:

buffSize = MAX_CHARS_INPUT;
ptr = malloc(buffSize*sizeof(*ptr));
i = 0;

虽然 re-mallocing 不是很明智,因为如果分配失败通常会有更大的问题(除非内存非常有限)。并且(特别是因为您没有检查 malloc 的结果)可能有问题,因为 malloc 也可能失败。在分配失败后退出程序并不罕见。

【讨论】:

    【解决方案2】:

    您的代码很少有错误,新代码是:

      #include <stdio.h>
      #include <stdlib.h>
    
      #define MAX_CHARS_INPUT 200
      #define D_SIZE 2
    
      void printWithMalloc(){
          //int charSize=1; you don't need this.
          //int *ptr=malloc(MAX_CHARS_INPUT*sizeof(charSize));
          char *ptr=malloc(MAX_CHARS_INPUT*sizeof(char));//sizeof(char) will give you the block size, MAX_CHARS_INPUT: gives you the number of blocks to be allocated and pointer type is char, since you want to save char(s), right?
    
          int i=0, j=0, c;
          printf("please enter a string\n");
    
          //while ((c=getchar())!=EOF && c!='\n')
           while ((c=getchar())!='\r') //'\r' is for enter key... since the user input is coming from console not form a file, right?
          {
              ptr[i++]=c;
              if (i==(MAX_CHARS_INPUT-1)) /*if we need to realloc*/
              if (i==MAX_CHARS_INPUT) // i is already incremented in i++
              {
                  //int *temp=realloc(ptr,D_SIZE*MAX_CHARS_INPUT*sizeof(charSize));
                  char *temp=realloc(ptr,D_SIZE*MAX_CHARS_INPUT*sizeof(char));
                  if (temp==NULL) /*realloc failed*/
                  {
                      printf("you wrote:\n");
                      while(j<=i)
                          putchar(ptr[j++]);
    
                      free(ptr);
                      ptr=(char*)malloc(MAX_CHARS_INPUT*sizeof(char));
                  }
                  else
                      ptr=temp;
              }
          }
      }
    
      int main(){
          printWithMalloc();
          return 0;
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-26
      • 2020-11-12
      • 1970-01-01
      • 2016-04-10
      相关资源
      最近更新 更多