Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.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
文献中未解释的可变大小自动分配(ALOCA)的使用_C_Memory Management_Dynamic Memory Allocation - Fatal编程技术网

文献中未解释的可变大小自动分配(ALOCA)的使用

文献中未解释的可变大小自动分配(ALOCA)的使用,c,memory-management,dynamic-memory-allocation,C,Memory Management,Dynamic Memory Allocation,我正在阅读嵌入式软件的基础知识-C和汇编语言在其中相遇(2001),并获得了以下代码: FILE *OpenFile(char *name, char *ext, char *mode) { int size = strlen(name) + strlen(ext) + 2; char *filespec = (char *) alloca(size); sprintf(filespec, "%s.%s", name, ext); return fopen(fil

我正在阅读嵌入式软件的基础知识-C和汇编语言在其中相遇(2001),并获得了以下代码:

FILE *OpenFile(char *name, char *ext, char *mode)
{
    int size = strlen(name) + strlen(ext) + 2;
    char *filespec = (char *) alloca(size);
    sprintf(filespec, "%s.%s", name, ext);
    return fopen(filespec, mode);
}
作者没有阐明alloca为什么有用,或者它实现了什么。他声称“从堆中分配动态内存的最常见原因是对象的大小直到执行时才知道…”


然而,我不明白为什么他不能只写
char*filespec=(char*)size在第4行。

现在不要在程序中使用
alloca
,请:-)
它与(char*)大小不同!它与char filespec[size]
相同,但他会使用它,因为他的编译器中可能没有VLA(可变长度数组)(它们来自C99,您应该使用它们)除了可能无法访问嵌入式应用程序中的堆之外。

最近不要在程序中使用
alloca
,请:-) 它与(char*)大小不同!它与char filespec[size]相同,但他会使用它,因为VLA(可变长度数组)可能在他的编译器中不可用(它们来自C99,您应该使用它们),而且可能无法访问嵌入式应用程序中的堆。

在堆栈上分配,这意味着它将在函数结束后解除分配,不需要手动释放。在堆上分配,需要手动释放。这两种功能根本不同。(你没有问过马洛克,但我想你可能会问。)

另外,您描述的显式强制转换也不会进行任何分配,它只是进行了一次强制转换,据我所知,这种转换没有任何意义。这种强制转换不能使代码正确。

在堆栈上分配,这意味着它将在函数结束后被释放,不需要手动释放。在堆上分配,需要手动释放。这两种功能根本不同。(你没有问过马洛克,但我想你可能会问。)


另外,您描述的显式强制转换也不会进行任何分配,它只是进行了一次强制转换,据我所知,这种转换没有任何意义。该强制转换不会使代码正确。

alloca
用于动态分配堆栈上的空间(移动堆栈指针)。因为在编译时您不知道名称和ext大小,所以应该动态地(在运行时)分配它。它可以在堆(malloc和friends)或堆栈(alloca)中完成。或者在C99中使用VLA,正如所有其他评论者所写的那样)char*filespec=(char*)size;在第4行,当您尝试取消引用size变量时,它会将size变量强制转换为一个指针,结果非常糟糕。也就是说,如果大小为30,那么filespec将是指向30.@B.Lee yes的内存位置的指针。堆栈变量具有自动存储持续时间,因为退出函数时会自动删除它们。您不需要释放它们(对于基于堆的数据,您可能需要这样做)。它们也更快,但堆栈并不像堆那个么大,在运行时总是被清除returns@user996142为了迂腐,函数返回后堆栈总是无效的。我怀疑它是否真的被清除了。@B.Lee:是的(我自己在嵌入式项目中使用它,例如TLS)。让它成为可选的是C11IMO中最糟糕的决定之一。您应该明确地对C实现如何工作和C语言进行更多的研究。如果你已经(无意冒犯)了,你就不会要求其他选择。只要使用VLA。支持C99的编译器不太可能在C11模式下提供相同的功能。
alloca
用于动态分配堆栈上的空间(移动堆栈指针)。因为在编译时您不知道名称和ext大小,所以应该动态地(在运行时)分配它。它可以在堆(malloc和friends)或堆栈(alloca)中完成。或者在C99中使用VLA,正如所有其他评论者所写的那样)char*filespec=(char*)size;在第4行,当您尝试取消引用size变量时,它会将size变量强制转换为一个指针,结果非常糟糕。也就是说,如果大小为30,那么filespec将是指向30.@B.Lee yes的内存位置的指针。堆栈变量具有自动存储持续时间,因为退出函数时会自动删除它们。您不需要释放它们(对于基于堆的数据,您可能需要这样做)。它们也更快,但堆栈并不像堆那个么大,在运行时总是被清除returns@user996142为了迂腐,函数返回后堆栈总是无效的。我怀疑它是否真的被清除了。@B.Lee:是的(我自己在嵌入式项目中使用它,例如TLS)。让它成为可选的是C11IMO中最糟糕的决定之一。您应该明确地对C实现如何工作和C语言进行更多的研究。如果你已经(无意冒犯)了,你就不会要求其他选择。只要使用VLA。支持C99的编译器不太可能在C11模式下不提供相同的功能。只是澄清一下:C99支持动态大小的数组,因此在这种情况下不需要alloca,因为可以使用动态大小?@dune.rocks我对VSA很好奇;作者实际上在同一个例子中使用了VSA。然而,他提到alloca在函数中有多个返回时是有用的。你不同意这一点吗?(也许我应该得到一本更新的书)我不喜欢这里的术语
动态大小
,因为人们会立即想到堆。它们被称为可变长度数组,如果你有权访问最近的ish工具链,你可以使用它们而不是allocaI。如果你不同意这一点,你认为返回的数量有什么区别?VLA在范围出口(例如函数返回)上也会被删除,因为它们存在于堆栈上。编译器将为您分配可变的堆栈空间(顺便说一下,使用alloca的UndertheHood)只是为了澄清:C99支持动态大小的数组,因此在这种情况下不需要alloca,因为动态si