首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C -language动态内存

C -language动态内存
EN

Stack Overflow用户
提问于 2010-10-04 18:27:34
回答 5查看 244关注 0票数 1

大家好,感谢大家的支持,但是没有人给我提供所需的信息,现在我试着这样做

代码语言:javascript
复制
#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 ;
}

我在编译时编译了它,它显示warnig,如下所示

代码语言:javascript
复制
c:8: warning: assignment from incompatible pointer type

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

EN

回答 5

Stack Overflow用户

发布于 2010-10-04 18:39:58

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

代码语言:javascript
复制
a = (int **) malloc(sizeof(int *) * 5);

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

代码语言:javascript
复制
a = malloc(5 * sizeof *a);

注意:没有强制转换,没有提到类型。第二个malloc将如下所示

代码语言:javascript
复制
a[i] = malloc(3 * sizeof *a[i]);

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

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

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

票数 5
EN

Stack Overflow用户

发布于 2010-10-04 18:41:48

这段代码有几个错误。首先,警告是指您试图将指向整数的指针(int *)赋给一个变量(a),该变量是指向指向整数(int **)的指针的变量,而您实际上希望将其用作数组的数组。

所以,第一个更正,在第8行不是

代码语言:javascript
复制
a=(int*)malloc(sizeof(int)*5);

但它是

代码语言:javascript
复制
a=(int**)malloc(sizeof(int *)*5);

(使用C语言进行强制转换并不是必须的,但作为一名C++程序员,我更愿意保持这种方式)

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

然后,在应用程序结束时,只对第一个malloc分配的空间执行free操作,同时进行其他五次分配(每行一次)。因此,您可以在显示每一行之后的最后一个周期中执行释放。

代码语言:javascript
复制
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上,这样做可能是可以的:

代码语言:javascript
复制
void ClearScreen()
{
    fputs("\x1B[2J\x1B[1;1H", stdout);
    fflush(stdout);
}
票数 3
EN

Stack Overflow用户

发布于 2010-10-04 18:33:53

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

代码语言:javascript
复制
a = (int*)malloc(sizeof(int)*5);

应该是

代码语言:javascript
复制
a = malloc(sizeof(int*)*5);
                   ^

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

你可能想要读这篇文章:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3854337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档