【问题标题】:c -language dynamic memoryc语言动态内存
【发布时间】:2011-04-20 17:45:27
【问题描述】:

大家好,感谢大家的支持,但现在没有人向我提供所需的信息,我尝试像这样执行该程序

#include<stdio.h>
#include <stdlib.h>
int main()
{
    int **a,i,j;
    system("clear");

    a=(int*)malloc(sizeof(int)*5);

    for (i=0; i<5; i++)
    {
        a[i]= malloc(sizeof(int)*3);

        for (j=0; j<3; j++)
        {
            printf("\nplease enter the [%d][%d] location = ",i,j);
            scanf("%d",&a[i][j]);
        }
    }


    for (i=0; i<5; i++)
    {
        for (j=0; j<3; j++)
        {
            printf("\nthe value enter  enter the [%d][%d] location = ",i,j);
            printf("%d",a[i][j]);
        }
    }
    free(a);
    return ;
}

我在编译时遵守它,它显示以下警告

c:8: warning: assignment from incompatible pointer type

在运行程序时,它从用户那里获取 15 个值,但它没有显示用户输入的值 谁能解释我做错了什么,任何人都可以解释一下双指针和动态内存分配的概念

【问题讨论】:

  • 请格式化您的代码。
  • 格式已修复,请避免再次发这样的代码,伤害大家的眼睛。
  • 可能重复(同一用户):c - dynamic memory
  • 你应该努力改进你的原始问题而不是重复它 - 也试着更仔细地阅读你之前问题的答案

标签: c


【解决方案1】:

a 指向int 指针数组。所以该数组的每个元素的类型都是int* 而不是int。所以你应该使用sizeof(int*)

这个

a = (int*)malloc(sizeof(int)*5);

应该是

a = malloc(sizeof(int*)*5);
                   ^

由于 C 中的 malloc 返回一个 void 指针,并且 C 隐式地从 void* 转换为 void*,因此不需要转换。

您可能想阅读以下内容:

Should I explicitly cast malloc()'s return value?

【讨论】:

  • 你应该提到你为什么去掉了那个丑陋的不需要的演员。
【解决方案2】:
   a = (int*)malloc(sizeof(int)*5);
     ^
     |
Warning due to this

a 是指向int 的指针,即int **

您将malloc() 的返回值转换为int*,然后将其分配给int**,因此从int*int** 的隐式转换会生成警告。此外,它应该是 sizeof(int *) 内的第一个 malloc() [因为您正在尝试为二维数组分配内存]。

试试这个:

a=(int**)malloc(sizeof(int*)*5);

【讨论】:

  • 你忘记了缺少的免费。
【解决方案3】:

在第 6 行你应该有

a = (int**) malloc(sizeof(int*) * 5)); 

【讨论】:

    【解决方案4】:

    首先,您的代码中的内存分配不正确。第一个malloc 应该如下所示

    a = (int **) malloc(sizeof(int *) * 5);
    

    您的aint **,正如您声明的那样。您将malloc 的结果转换为int *int *int ** 是编译器警告您的不兼容类型。为避免以后出现此类错误,请改掉在语句中使用类型的坏习惯。 C 中的类型属于声明语句 应尽可能与类型无关。上面的malloc 调用这样看起来会好很多

    a = malloc(5 * sizeof *a);
    

    注意:没有演员表,没有提到类型。第二个malloc 如下所示

    a[i] = malloc(3 * sizeof *a[i]);
    

    我希望您看到这些malloc 调用的构建模式。

    您还忘记为程序中的各个子数组释放内存(a[i] 内存永远不会被释放,而a 内存会)。

    至于程序没有显示输入的值...第一个问题是malloc 调用中断的严重程度足以阻止您的程序工作,但它仍然可能在某些平台上“工作”。在这样的平台上,它应该显示值。你确定你不是简单地错过了输出吗?

    【讨论】:

      【解决方案5】:

      此代码有几个错误。首先,警告指的是您试图将指向整数 (int *) 的指针分配给变量 (a),该变量是指向整数指针 (int **) 的指针,它您实际上想用作数组数组。

      所以,第一次更正,第 8 行不是

      a=(int*)malloc(sizeof(int)*5);
      

      但它是

      a=(int**)malloc(sizeof(int *)*5);
      

      (在 C 中强制转换 并不是绝对必要的,但作为 C++ 程序员,我更喜欢保持这种状态)

      注意sizeof 中的表达式也发生了变化,因为您要分配的不是五个整数的空间,而是五个指向整数的指针的空间。

      然后,在应用程序结束时,free 只分配了第一个 malloc 分配的空间,而您进行了其他五个分配(每行一个)。因此,您可以在显示每一行之后的最后一个循环中进行释放。

      for (i=0; i<5; i++)
      {
          for (j=0; j<3; j++)
          {
              printf("\nthe value enter  enter the [%d][%d] location = ",i,j);
              printf("%d",a[i][j]);
          }
          free(a[i]);
          a[i]=NULL;
      }
      free(a);
      a=NULL;
      

      记住:对于每个malloccalloc,你必须有它对应的free,否则你会泄漏内存。

      在这里,在每次释放后,我将相应的指针设置为NULL,以丢弃那些旧的、现在无效的指针。有人说这种行为可以掩盖双重释放(因为free(NULL) 不会产生错误),但恕我直言,这比替代方法更好

      一个重要的细节:您没有检查malloc 的返回值,这很糟糕。在这样的小程序中分配失败的可能性极小,但是,最好始终检查malloc 的返回值是否为NULL,在这种情况下,处理优雅的情况,通常释放所有资源并关闭应用程序。

      顺便说一句,system("clear"); 很丑。您应该使用特定于平台的方式来清洁屏幕,如果包含在一个函数中会更好;在具有普通 (X3.64) 终端仿真器的 Linux 上,这样的事情可能没问题:

      void ClearScreen()
      {
          fputs("\x1B[2J\x1B[1;1H", stdout);
          fflush(stdout);
      }
      

      【讨论】:

        猜你喜欢
        • 2011-09-13
        • 2016-07-17
        • 2017-10-02
        • 2021-03-19
        • 2020-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多