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
不能是有效的数组大小。我真的不知道 l2
和 h2
是什么(正如我在评论中所说,使用这样的变量名就像写一本小说,其中有 20 个不同的角色都命名为“Sue”),但我可以猜测它们都是正在排序的数组中的索引。将两个索引加在一起是完全没有意义的行为。 (一个有意义的和是一个起点和一个长度,而不是一个起点和一个终点。)
因此,除了 temp
作为 VLA 之外,它还是一个大小未正确计算的 VLA。
我正在尝试学习使用 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
不能是有效的数组大小。我真的不知道 l2
和 h2
是什么(正如我在评论中所说,使用这样的变量名就像写一本小说,其中有 20 个不同的角色都命名为“Sue”),但我可以猜测它们都是正在排序的数组中的索引。将两个索引加在一起是完全没有意义的行为。 (一个有意义的和是一个起点和一个长度,而不是一个起点和一个终点。)
因此,除了 temp
作为 VLA 之外,它还是一个大小未正确计算的 VLA。