C malloc 函数大小
C malloc function size
所以我需要回答这个棘手的小问题:
如果函数是:
c+9指向内存中的哪个段
void f()
{
int *c=(int*)malloc(10);
}
我想我知道 malloc 是如何工作的,我查了其他问题,所以这应该分配 10 个字节的内存和 return 第一个的地址,加上它会将它转换为 int。
所以因为 sizeof(int)
是 4 个字节,所以我认为 space 不够 9 个整数,并且 c+9 会指向分配内存范围之外的一些内存它会 return 一个错误,但是不,程序工作得很好,就好像分配了 10*sizeof(int)
一样。那我错在哪里了?
如果您超出分配的内存范围,C 程序将不会 return 出错。结果未定义,它可能挂起或(显然)工作正常。但是不行。
你的错误是认为它工作得很好。
是的,它可能会运行,是的,它可能不会出现段错误,但不,它是不正确的。
So because sizeof(int) is 4 bytes, I thought that there wouldn't be enough space for 9 integers, and c+9 would point to some memory outside the range of the allocated memory
这是正确的
and it would return an error
但不幸的是,这并非在所有情况下都是正确的。 OS 只能给出整页的 space,这意味着你只能得到 4096 字节(一页)的倍数的 space。这意味着,即使 malloc(在 userspace 中实现)给了你 10 个字节,你的程序从 OS 中至少有 4096 个字节。 但是:malloc 会最终 从你得到的这一页中给你更多未分配的 space 然后它 会 可能引入了一个错误。
TLDR:这是 UB,即使它看起来有效,也不要这样做。
您错误地假设未定义的行为意味着某些 "bad" 一定会发生。在你的情况下访问 c[9]
是未定义的行为,因为你没有 malloc
ed 足够的内存 - 这是你不应该做的事情。
未定义的行为意味着标准允许任何行为。对于这个特定的错误,您经常会遇到非本地化的错误行为,访问 c[9]
显然可以正常工作,并且在您执行此操作时不会发生任何奇怪的事情,但是随后在一段不相关的代码中访问一段不相关的数据会导致错误。通常这些类型的错误也会破坏内存分配系统使用的数据,这可能会使 malloc
和 free
行为不端。
你是对的 malloc
给你 10 个字符(通常是 8 位字节)。为 int
分配一个不是 int
大小倍数的区域本身就是可疑的……但不是非法的。生成的地址被解释为指向 int
(通常为 32 位)的指针,并且您要求在分配区域的开头之外的地址 9 int
。这本身很好,但试图访问它是未定义的行为:任何事情都可能发生,包括您天真地期望的任何事情,什么都没有,崩溃或终结宇宙。 通常 会发生的是,您从包含其他对象的更大区域分配内存并释放 space(额外数据 malloc
用于跟踪整个混乱)。 读取没有危害,写入可能会损坏其他数据或弄乱malloc
的数据结构,导致神秘的behaviour/crashes 稍后。运气好的话,新的space分配在一个边界,越界访问就报segmentation fault,指向罪魁祸首
所以我需要回答这个棘手的小问题:
如果函数是:
c+9指向内存中的哪个段void f()
{
int *c=(int*)malloc(10);
}
我想我知道 malloc 是如何工作的,我查了其他问题,所以这应该分配 10 个字节的内存和 return 第一个的地址,加上它会将它转换为 int。
所以因为 sizeof(int)
是 4 个字节,所以我认为 space 不够 9 个整数,并且 c+9 会指向分配内存范围之外的一些内存它会 return 一个错误,但是不,程序工作得很好,就好像分配了 10*sizeof(int)
一样。那我错在哪里了?
如果您超出分配的内存范围,C 程序将不会 return 出错。结果未定义,它可能挂起或(显然)工作正常。但是不行。
你的错误是认为它工作得很好。
是的,它可能会运行,是的,它可能不会出现段错误,但不,它是不正确的。
So because sizeof(int) is 4 bytes, I thought that there wouldn't be enough space for 9 integers, and c+9 would point to some memory outside the range of the allocated memory
这是正确的
and it would return an error
但不幸的是,这并非在所有情况下都是正确的。 OS 只能给出整页的 space,这意味着你只能得到 4096 字节(一页)的倍数的 space。这意味着,即使 malloc(在 userspace 中实现)给了你 10 个字节,你的程序从 OS 中至少有 4096 个字节。 但是:malloc 会最终 从你得到的这一页中给你更多未分配的 space 然后它 会 可能引入了一个错误。
TLDR:这是 UB,即使它看起来有效,也不要这样做。
您错误地假设未定义的行为意味着某些 "bad" 一定会发生。在你的情况下访问 c[9]
是未定义的行为,因为你没有 malloc
ed 足够的内存 - 这是你不应该做的事情。
未定义的行为意味着标准允许任何行为。对于这个特定的错误,您经常会遇到非本地化的错误行为,访问 c[9]
显然可以正常工作,并且在您执行此操作时不会发生任何奇怪的事情,但是随后在一段不相关的代码中访问一段不相关的数据会导致错误。通常这些类型的错误也会破坏内存分配系统使用的数据,这可能会使 malloc
和 free
行为不端。
你是对的 malloc
给你 10 个字符(通常是 8 位字节)。为 int
分配一个不是 int
大小倍数的区域本身就是可疑的……但不是非法的。生成的地址被解释为指向 int
(通常为 32 位)的指针,并且您要求在分配区域的开头之外的地址 9 int
。这本身很好,但试图访问它是未定义的行为:任何事情都可能发生,包括您天真地期望的任何事情,什么都没有,崩溃或终结宇宙。 通常 会发生的是,您从包含其他对象的更大区域分配内存并释放 space(额外数据 malloc
用于跟踪整个混乱)。 读取没有危害,写入可能会损坏其他数据或弄乱malloc
的数据结构,导致神秘的behaviour/crashes 稍后。运气好的话,新的space分配在一个边界,越界访问就报segmentation fault,指向罪魁祸首