-2

我是 C 编程的初学者。最近有人教我如何使用malloc,但我认为我不太了解它。就像事实上为什么它需要一个void *或任何类型转换?为什么语法本身(void *)void *malloc(size_t size). 分配给函数的变量如何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();
}

在此我们将studentInfo指针分配给 malloc 函数,对吗?那么......如何studentInfo知道内存块的地址是美国而不是南极洲?而且我知道用其他数据类型对 malloc 进行类型转换不是一个好习惯。但是为什么(int *)。为什么 malloc 需要一个指针?如果 malloc 需要一个指针,这意味着它正在返回一个地址,对吗?我向我的朋友问过这个问题,他说没有 malloc 不会返回任何东西。还有一件事是我们需要将类型转换放在括号中吗?

请用非常简单的术语解释。谢谢你。

4

3 回答 3

0

malloc函数调用分配一个足够大的内存块来保存对象j*k int,并返回该块的第一个元素的地址——该地址值被分配给studentInfo,给我们这样的东西:

             int *       int
             +–––+       +–––+
studentInfo: |   | ––––&gt; |   |
             +–––+       +–––+
                         |   |
                         +–––+
                          ...

因此,studentInfo指向(存储地址)该int序列中的第一个对象。

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

只有两种情况您必须转换结果malloc

  • 您正在将代码编译为 C++;
  • 您正在使用古老的K&R C 编译器;

与 C 不同,C++ 不允许直接分配void *给其他指针类型。

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

否则,通常最好不要投射结果 - 这可能会导致维护问题。写成这样会更干净一些

studentInfo = malloc( sizeof *studentInfo * j * k );

由于 的类型studentInfoint *,表达式的类型*studentInfoint,所以 的结果sizeof *studentInfo与 相同sizeof (int)

请记住,这sizeof是一个操作符,而不是一个函数——仅当操作数是类型名称时才需要括号。

于 2021-03-21T20:25:54.510 回答
0

malloc returns void* because malloc allocates not only int, it can allocate floats, doubles even structures etc. Reason of returning pointer is because it can allocate so much memory in heap, heap is larger than stack and if allocated memory is so big for stack you will receive an error(probably stackoverflow) + copy memory is meaningless if we just can copy its address and refer it by pointer. And void * is a special kind that everything can be assigned no matter what type of address it is. Yes you need to cast it, if you don't then compiler will give you an error

于 2021-03-21T06:59:43.130 回答
0

为什么语法本身在 void *malloc(size_t size) 中有 (void *)。

因为malloc是一个函数,而函数有一个返回类型。这告诉这个函数返回这个特定的类型。所以(void *)意味着malloc返回一个void *.

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

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

在这里,我们为 studentInfo 指针分配了 malloc 函数,对吗?那么... studentInfo 怎么知道内存块的地址是美国而不是南极洲?

不完全是。studentInfo没有分配malloc函数,而是指向由 .studentInfo返回的指针malloc。这studentInfo现在指向分配的内存。

为什么 malloc 需要一个指针?

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

您不需要在这里进行类型转换,因为void *它是自动提升的。

还有一件事是我们需要将类型转换放在括号中吗?

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

于 2021-03-21T06:54:16.697 回答