Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 理解动态内存分配_C_Pointers_Multidimensional Array_Malloc_Dynamic Memory Allocation - Fatal编程技术网

C 理解动态内存分配

C 理解动态内存分配,c,pointers,multidimensional-array,malloc,dynamic-memory-allocation,C,Pointers,Multidimensional Array,Malloc,Dynamic Memory Allocation,我是C编程的初学者。最近有人教我如何使用malloc,但我觉得我不太懂。比如,为什么它需要一个void*或任何类型转换?为什么语法本身在void*malloc(size\u t size)中有(void*)。分配给malloc函数的变量如何知道内存块从何处开始?malloc函数在分配内存块后是否返回地址或其他内容 在课堂上,我们的教授给了我们这个课程。我也了解2d内存分配的工作原理 #include<stdio.h> #include<conio.h> void main

我是C编程的初学者。最近有人教我如何使用
malloc
,但我觉得我不太懂。比如,为什么它需要一个
void*
或任何类型转换?为什么语法本身在
void*malloc(size\u t size)
中有
(void*)
。分配给
malloc
函数的变量如何知道内存块从何处开始?
malloc
函数在分配内存块后是否返回地址或其他内容

在课堂上,我们的教授给了我们这个课程。我也了解2d内存分配的工作原理

#include<stdio.h>
#include<conio.h>
void main(void)
{
    int *studentInfo=NULL,i=1,j=10,k=0,l=0;
    //int *studInfo[10];
    int memLoc=0;
    clrscr();

    printf("How many Student Information You want to store:");
    scanf("%d",&j);
    printf("How many Subject Marks per student You want to store:");
    scanf("%d",&k);
    studentInfo=(int *)malloc(j*k*sizeof(int));

    //memLoc=0;
    for(l=0;l<j;l++)
    {
        printf("Enter Marks for %dth Student",l+1);
        for(i=0;i<k;i++)
        {
            printf("\nEnter Marks for Subject %d:",i+1);
            scanf("%d",studentInfo+(l*j)+i);
        }
    }
    //3 students and 3 subjects
    //memory allocated=3*3*2=18
    //0,1,2 student 0*no of students
    //3 4 5 student 1
    //6 7 8 student 2

    printf("\nInformation you Entered\n");
    for(l=0;l<j;l++)
    {
        printf("Makrs of Student %d:",l+1);
        for(i=0;i<k;i++)
            printf("\t%d",*(studentInfo+(l*j)+i));
        printf("\n");
    }

    //*(studentInfo)=10;
    //*(studentInfo+1)=20;
    //*(studentInfo+2)=30;
    //printf("%d\n",sizeof(studentInfo));
    //printf("%d\n",*(studentInfo));
    //printf("%d\n",*(studentInfo+i++));
    //printf("%d\n",*(studentInfo+i++));


    free(studentInfo);
    getch();
}
#包括
#包括
真空总管(真空)
{
int*studentInfo=NULL,i=1,j=10,k=0,l=0;
//int*studInfo[10];
int-memLoc=0;
clrsc();
printf(“要存储多少学生信息:”);
scanf(“%d”和“&j”);
printf(“每个学生要存储的科目分数:”);
scanf(“%d”和“&k”);
studentInfo=(int*)malloc(j*k*sizeof(int));
//memLoc=0;
对于(l=0;l
为什么语法本身在void*malloc(size\u t size)中有(void*)

因为
malloc
是一个函数,函数有一个返回类型。这说明这个函数返回这个特定类型。所以
(void*)
意味着
malloc
返回一个
void*

malloc函数在分配内存块后是否返回地址或其他内容

Malloc将指定大小的内存分配到堆中,并返回指向该分配内存的指针

在这里,我们给studentInfo指针分配了malloc函数,对吗?那么,studentInfo如何知道内存块的地址是USA而不是南极洲

不完全正确。
studentInfo
未分配
malloc
函数,但
studentInfo
指向由
malloc
返回的指针。这是
studentInfo
现在指向分配的内存

为什么malloc需要一个指针

malloc
不需要指针。它将要分配的内存量作为参数

您不需要在此处进行类型转换,因为
void*
会自动升级

还有一件事,我们需要把类型转换放在括号里吗


是的,这就是类型转换的语法。没有括号,它将导致编译错误。

malloc
返回
void*
,因为
malloc
不仅分配
int
,还可以分配浮点、双倍甚至结构等。返回指针的原因是它可以在堆中分配如此多的内存,堆比堆栈大,如果为堆栈分配的内存太大,您将收到一个错误(可能是stackoverflow)+复制内存是没有意义的,如果我们只需要复制它的地址并用指针引用它。
void*
是一种特殊的类型,任何东西都可以被分配,不管它是什么类型的地址。是的,你需要强制转换它,如果你不这样做,编译器会给你一个错误。
malloc
函数调用分配一块内存ge足以容纳
j*k
int
对象,并返回该块第一个元素的地址-该地址值被分配给
studentInfo
,这给了我们如下信息:

             int *       int
             +–––+       +–––+
studentInfo: |   | ––––> |   |
             +–––+       +–––+
                         |   |
                         +–––+
                          ...
因此,
studentInfo
指向(存储)该序列中第一个
int
对象的地址

在代码中调用
malloc
之前的
(int*)
是一个强制转换-它意味着“将以下表达式的结果(malloc
返回的值)视为
int*
,或指向
int
的指针”

只有两种情况下您必须强制转换malloc的结果:

    <>你编译代码为C++,
  • 您正在使用一个古老的K&R C编译器

不像C,C++不允许直接将<代码> VUL*>代码>分配给其他指针类型。

此外,在C89标准之前,
malloc
返回
char*
,因此需要强制转换才能将结果分配给任何其他指针类型

否则,通常最好不要强制转换结果——这可能会导致维护方面的麻烦。将其写成

studentInfo = malloc( sizeof *studentInfo * j * k );
由于
studentInfo
的类型是
int*
,表达式
*studentInfo
的类型是
int
,因此
sizeof*studentInfo
的结果与
sizeof(int)
相同


<>记住<代码> sieOS/<代码>是一个运算符,不是函数。只有操作数是类型名时才需要PARNE.< /P>我认为C++是多余的,也是不必要的,除非你必须用C++来使用<代码> MalOC/<代码>。你的意思是什么。
malloc
返回分配内存的地址。它不在内存中放任何东西。你是将数据写入内存块的人,因此你应该知道每个块将包含什么。如果malloc需要一个指针,这意味着它正在返回一个地址,对吗?。没有必要与任何人争论。只需r它告诉您返回的确切内容:malloc()和calloc()函数返回一个指向分配内存的指针“为什么malloc需要一个指针??如果malloc需要一个指针,这意味着它返回的地址是正确的?”是的,它返回一个地址。如果不将地址输入指针,分配的内存将丢失,并且您将有内存泄漏。@kaylum这是我说内存块的地址不是a而是B的方式。不完全是。studentInfo没有分配malloc函数,但studentInfo指向malloc.Thi返回的指针s was studentInfo现在指向分配的内存。因此,这意味着它正在