- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我最近一直在尝试理解严格别名的一个特定方面,我认为我已经制作了尽可能最小的有趣代码。 (对我来说很有趣,就是这样!)
更新:根据到目前为止的答案,很明显我需要澄清这个问题。从某个角度来看,这里的第一个列表是“明显”定义的行为。真正的问题是在自定义分配器和自定义内存池中遵循此逻辑。如果我 malloc
开头一大块内存,然后自己写my_malloc
和 my_free
使用那个单一的大块,然后是UB,理由是它不使用官方free
?
我会坚持使用 C,有点武断。我的印象是更容易谈论,C 标准更清晰一些。
int main() {
uint32_t *p32 = malloc(4);
*p32 = 0;
free(p32);
uint16_t *p16 = malloc(4);
p16[0] = 7;
p16[1] = 7;
free(p16);
}
malloc
将返回与第一个
malloc
相同的地址(因为它是
free
d 之间)。这意味着它使用两种不同的类型访问相同的内存,这违反了严格的别名。那么以上肯定是未定义的行为(UB)吗?
malloc
总是成功。我可以添加对
malloc
返回值的检查,但这只会使问题变得困惑)
malloc
和
free
(和
calloc
/
realloc
/...)是否允许“删除”与特定地址关联的类型,允许进一步访问以在地址上“印记”新类型?
malloc
/
free
是特殊的,那么这是否意味着我不能合法地编写自己的分配器来克隆
malloc
的行为? ?我确信有很多项目都带有自定义分配器——它们都是 UB 吗?
gcc
和
clang
基本上尊重我的(激进的)重新解释。如果是这样,也许应该相应地编辑标准?我关于
gcc
的“证据”和
clang
很难描述,它使用
memmove
具有相同的源和目标(因此被优化掉)以这样一种方式阻止任何不需要的优化,因为它告诉编译器将来通过目标指针读取的内容将为之前通过源指针写入的位模式别名。我能够相应地阻止不受欢迎的解释。但我想这并不是真正的“证据”,也许我只是幸运。 UB 显然意味着编译器也允许给我误导性的结果!
memcpy
和
memmove
变得特殊,就像
malloc
可能是特殊的一样。允许它们将类型更改为目标指针的类型。这与我的“证据”一致。)
malloc
(和 friend )是特殊的。自定义分配器并不特殊,因此是 UB,除非它们为每种类型维护单独的内存池。此外,请参见示例 X一段极端的代码,其中编译器 Y 做了不受欢迎的事情,正是因为编译器 Y 在这方面非常严格,并且与这种重新解释相矛盾。”
malloc
怎么办? ed内存?是否同样适用。 (局部变量,静态变量,...)
最佳答案
以下是 C99 严格的别名规则(我希望是)它们的全部内容:
6.5
(6) The effective type of an object for an access to its stored value is the declared type of the object, if any. If a value is stored into an object having no declared type through an lvalue having a type that is not a character type, then the type of the lvalue becomes the effective type of the object for that access and for subsequent accesses that do not modify the stored value. If a value is copied into an object having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one. For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access.(7) An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
— a type compatible with the effective type of the object,
— a qualified version of a type compatible with the effective type of the object,
— a type that is the signed or unsigned type corresponding to the effective type of the object,
— a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
— an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
— a character type.
uint32_t
或两个
uint16_t
)。
int main() {
uint32_t *p32 = malloc(4);
*p32 = 0;
/* do not do this: free(p32); */
/* do not do this: uint16_t *p16 = malloc(4); */
/* do this instead: */
uint16_t *p16 = (uint16_t *)p32;
p16[0] = 7;
p16[1] = 7;
free(p16);
}
uint32_t
然后随后存储一个
uint16_t
在同一个地址,所以我们完全没问题。
关于c - malloc-free-malloc 和严格别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31534716/
这个问题在这里已经有了答案: How do free and malloc work in C? (8 个答案) 关闭 8 年前。 如果你使用malloc()为4个整数分配内存,它不应该返回第一个整
首先,介绍一下背景知识,这样您就不会认为我在尝试做一些疯狂的事情: 我正在尝试调试由其他人编写的 C 库中的崩溃。崩溃看起来像这样: TheProgram(44365,0x7fff75996310)
我正在 cstdlib malloc() 和 free() 函数之上创建自定义内存分配器(出于性能原因)。分配器位于一个简单的类中,该类存储一些内存缓冲区和其他参数。我想将释放内存的方法命名为 fre
我一直在解决这个练习,我不知道从哪里开始: 语言 B 是上下文无关的;语言 C 是 B 的子集:C 是否是上下文无关的?证明或反驳。 我试过使用闭包属性: C = B - ( (A* - C) ∩ B
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 8 年前。 Improve th
如果我想获得在 C 中进行 malloc 的指针的所有权,则 docs for the Python cffi package和 this answer假设使用 ffi.gc 和 lib.free 作
#include #include struct node { int value; struct node* next; }; typedef struct node node_
众所周知,Oracle 在 Java 11 中更改了 Java 许可证,要求 JDK 的商业用途需要付费许可证。然而,使用 OpenJDK 仍然是免费的。 我的 PC 上有一个 JDK 11 文件夹,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我是 C 的新手,在 Linux 中使用带有开关 gcc -g -std=c89 -Wall ... 的 gcc4.4.6 进行编程,我在许多函数深处遇到了这个错误我的程序名为 compute: **
在多线程编程中,我们可以找到两个或多个线程/任务之间的数据传输同步的不同术语。 什么时候我们可以说某个算法是: 1)Lock-Free 2)Wait-Free 3)Wait-Freedom 我明白无锁
我正在尝试使用我通过 malloc() 手动分配的数组来运行程序。我在程序末尾释放()这个数组,但我不断收到错误消息 *** glibc detector *** ./test: double fre
我将 libxml2 与 libxslt 一起用于 C++ 程序的 XML 处理。为了使用 XSL 转换 XML 文档,我使用了以下函数(删除了错误处理): xmlDocPtr transformXm
new/delete 关键字使用免费商店 malloc/free 关键字是使用堆 我看到某处写着new 使用malloc。怎么会这样?它们不在内存段中使用? 其次,我看到某处写道我们不能在new 之后
我有这个简单的代码,我想在 tutorialspoint.com 上运行 #include using namespace std; class Vehicle { string vehic
我需要创建一个函数来删除 c 中链表的前 n 个节点,并返回删除的节点数。如果列表小于 n,它应该变为空。 另外,我不能使用递归。 使用现在的代码,它可以工作,但我没有释放“已删除”节点的内存。如果我
我需要调试这段代码的帮助。我知道问题出在 malloc 和 free 中,但找不到确切的位置、原因和解决方法。请不要回答:“使用 gdb”,仅此而已。我会使用 gdb 来调试它,但我仍然不太了解它并且
这个问题在这里已经有了答案: Unable to free const pointers in C (12 个答案) 关闭 8 年前。 将 C++11 代码连接到某些 C 回调,我必须传递 cons
这是出于好奇,我试图找到我对之前问题的疑问的答案,但他们似乎没有答案。所以在这里问,我只是写了一个代码,我试图将内存分配给一个 int 指针(以填充一个数组)并将 int 值扫描到它。完成数组后,我想
我有两个免费的单子(monad),用于不同上下文中的不同操作。但是,如果特定操作位于上下文中,则一个(主要)DSL 需要包含另一个(action)DSL: import Control.Monad.F
我是一名优秀的程序员,十分优秀!