C 分配 - 为什么 visual studio 2019 要求我分配内存而 codeBlocks 不是?

C allocation - why is visual studio 2019 asking me to allocate memory and codeBlocks is not?

我正在尝试学习使用 Visual Code 2019。 我的问题是,当我 运行 一个代码时,我收到此错误消息,“预期常量表达式”,当我 运行 CodeBlocks 中的相同代码时,该函数可以正常工作。

进行 google 搜索我了解到我需要为这行代码分配内存 monster temp[l2 + h2];

我的问题是如何 malloc 这一行?为什么 visual studio 2019 要求我分配内存而 codeBlocks 不是?

void m_s_m(monster *list, int l1, int h1, int l2, int h2, int *comparisons, int *copies, int *block_copies, int *mallocs, int use_name, int use_weight)
{
    monster temp[l2+h2];
    int index = l1;
    int k=l1;
    (*mallocs)++;
    (*block_copies)++;
    while(l1<=h1 && l2<=h2)
    {
        (*comparisons)++;
        if(use_name == 1)
        {
            if(strcmp(list[l1].name, list[l2].name)<0)
            {
                (*copies)++;
                temp[index] = list[l1];
                l1 = l1++;
            }
            else
            {
                (*copies)++;
                temp[index] = list[l2];
                l2 = l2++;
            }
        }
        if(use_weight == 1)
        {
            if(list[l1].weight<list[l2].weight)
            {
                (*copies)++;
                temp[index] = list[l1];
                l1 = l1++;
            }
            else
            {
                (*copies)++;
                temp[index] = list[l2];
                l2 = l2++;
            }
        }
        index++;
    }
    if(l1>h1)
    {
        (*block_copies)++;
        while(l2<=h2)
        {
            (*copies)++;
            (*comparisons)++;
            temp[index] = list[l2];
            index++;
            l2++;
        }
    }
    else
    {
        (*block_copies)++;
        while(l1<=h1)
        {
            (*copies)++;
            (*comparisons)++;
            temp[index] = list[l1];
            index++;
            l1++;
        }
    }
    (*block_copies)++;
    while(k<index)
    {
        (*copies)++;
        list[k]=temp[k];
        k++;
    }

}

有两个问题
monster temp[l2 + h2];

首先,它是一个可变长度数组 (VLA)。最初,C 要求您使用常量数组大小,因为编译器需要知道该数组将占用多少内存。但在 C99 中,应大众需求,C 允许声明局部数组,其大小在函数执行之前是未知的。事实上,一个函数调用和下一个函数调用之间的大小可能不同,这就是它们被称为可变长度的原因。 VLA 是 C11 的可选功能,主要是因为 Microsoft 不愿意实现它们。微软从未实施过它们。所以您不能将它们与 Microsoft C 编译器一起使用。

大多数其他 C 编译器都完全可以使用它们,我想您的代码块安装使用的是 Microsoft 编译器以外的某些 C 编译器。但是仅仅因为您可以使用 VLA 并不意味着它是一个好主意。如果你确定它适合堆栈,你应该只在堆栈上分配一个数组(无论它是固定长度还是可变长度)。这很棘手,因为您无法知道堆栈有多大,但假设堆栈足够大以容纳一些短数组是合理的。甚至没有办法给你一个指导方针,但在“桌面”操作系统上,你几乎可以肯定地摆脱了成千上万的元素。百万元素自找麻烦

VLA 的问题是您真的不知道阵列有多大。如果数组声明是一个编译时常量,有人可能会过来对你说,“是的,12 个整数的数组很好”,或者“卧槽,你正试图在堆栈上放置 1 亿个双精度数。”但是没有人知道 VLA。很可能有一天您 运行 程序的数组太大,它会崩溃或打开您的计算机以进行恶意收购或类似的操作。排序函数往往会被大型数组调用。

所以,是的,即使编译器不强制您这样做,也最好进行 malloc。

所以这是一个问题。另一个问题是 l2 + h2 不能是有效的数组大小。我真的不知道 l2h2 是什么(正如我在评论中所说,使用这样的变量名就像写一本小说,其中有 20 个不同的角色都命名为“Sue”),但我可以猜测它们都是正在排序的数组中的索引。将两个索引加在一起是完全没有意义的行为。 (一个有意义的和是一个起点和一个长度,而不是一个起点和一个终点。)

因此,除了 temp 作为 VLA 之外,它还是一个大小未正确计算的 VLA。