我size_t在C中感到困惑.我知道它是由sizeof运营商返回的.但究竟是什么呢?它是数据类型吗?
假设我有一个for循环:
for(i = 0; i < some_size; i++)
Run Code Online (Sandbox Code Playgroud)
我应该使用int i;或size_t i;?
在一本书中,我读了以下内容:
32位处理器具有2 ^ 32个可能的地址,而当前的64位处理器具有48位地址空间
我的期望是,如果它是一个64位处理器,地址空间也应该是2 ^ 64.
所以我想知道这种限制的原因是什么?
x86-64 cpu-architecture virtual-memory processor-architecture
我和这个答案的印象相同,size_t标准总是保证足够大以容纳给定系统的最大可能类型.
但是,此代码无法在gcc/Mingw上编译:
#include <stdint.h>
#include <stddef.h>
typedef uint8_t array_t [SIZE_MAX];
Run Code Online (Sandbox Code Playgroud)
错误:数组'array_t'的大小太大
我在这里误解了标准中的某些内容吗?被size_t允许为给定的实现是否过大?或者这是Mingw的另一个错误?
编辑:进一步的研究表明
typedef uint8_t array_t [SIZE_MAX/2]; // does compile
typedef uint8_t array_t [SIZE_MAX/2+1]; // does not compile
Run Code Online (Sandbox Code Playgroud)
这恰好是相同的
#include <limits.h>
typedef uint8_t array_t [LLONG_MAX]; // does compile
typedef uint8_t array_t [LLONG_MAX+(size_t)1]; // does not compile
Run Code Online (Sandbox Code Playgroud)
所以我现在倾向于认为这是Mingw中的一个错误,因为根据有符号整数类型设置最大允许大小没有任何意义.
应该使用C99中的数组索引的类型?它必须适用于LP32,ILP32,ILP64,LP64,LLP64等.它不一定是C89类型.
我找到了5位候选人:
size_tptrdiff_tintptr_t/uintptr_tint_fast*_t/uint_fast*_tint_least*_t/uint_least*_t有一个简单的代码可以更好地说明问题.什么是最好的类型i,并j在这两个特定的循环.如果有充分的理由,两种不同的类型也可以.
for (i=0; i<imax; i++) {
do_something(a[i]);
}
/* jmin can be less than 0 */
for (j=jmin; j<jmax; j++) {
do_something(a[j]);
}
Run Code Online (Sandbox Code Playgroud)
PS在问题的第一个版本中,我忘记了负面索引.
PPS我不打算编写C99编译器.但是编译器程序员的任何答案对我来说都是非常有价值的.
类似的问题:
我最近在回答一个关于p < q当p和q是指向不同对象/数组的指针时在C 中执行的未定义行为的问题。这让我想到:C ++ <在这种情况下具有相同(未定义)的行为,但是还提供了标准库模板std::less,该模板保证可以返回与<可以比较指针时相同的东西,并在不能比较时返回一些一致的顺序。
C是否提供具有类似功能的东西,从而可以安全地比较任意指针(相同类型)?我尝试浏览C11标准并没有发现任何东西,但是我在C中的经验比在C ++中小得多,因此我很容易错过一些东西。
c pointers memory-model undefined-behavior memory-segmentation
在"低级编程:英特尔®64架构上的C,汇编和程序执行"一书中,我读到:
每个虚拟64位地址(例如,我们在程序中使用的地址)由几个字段组成.地址本身实际上只有48位宽; 它被符号扩展为64位规范地址.它的特点是它的17个左位是相等的.如果不满足条件,则在使用时立即拒绝该地址.然后借助特殊表将48位虚拟地址转换为52位物理地址.
为什么虚拟地址和物理地址之间的差异为4位?
assembly memory-management virtual-memory memory-address mmu
怎么决定?这取决于编译器/架构/主机系统吗?
例:
int array[0x8000000000000000];
Run Code Online (Sandbox Code Playgroud)
对于x86_64位系统中的这一行,GCC输出:
Error "size of array 'array' is too large".
Run Code Online (Sandbox Code Playgroud) 我看到几个关于size_t与uintptr_t/ptrdiff_t的帖子(例如size_t与uintptr_t),但没有关于这些新的c99 ptr大小类型的相对大小.
示例机器:vanilla ubuntu 14lts x64,gcc 4.8:
printf("%zu, %zu, %zu\n", sizeof(uintptr_t), sizeof(intptr_t), sizeof(ptrdiff_t));
Run Code Online (Sandbox Code Playgroud)
打印:"8,8,8"
这对我来说没有意义,因为我期望必须签名的diff类型需要比unsigned ptr本身更多的位.
考虑:
NULL - (2^64-1) /*largest ptr, 64bits of 1's.*/
Run Code Online (Sandbox Code Playgroud)
这是2的补码负数不适合64位; 因此我希望ptrdiff_t大于ptr_t.
[一个相关的问题是为什么intptr_t与uintptr_t的大小相同....虽然我很舒服这可能只是为了允许一个带符号的类型来包含表示的位(例如,在负ptr上使用带符号的算法将是(a)be undefined,和(b)实用性有限,因为ptrs根据定义是"正面的")]
谢谢!
在C++中,我们都知道数组可以作为局部变量在"主"范围内:
int main(){
int arr[10000]; //on the stack, size can't be very large
....
}
Run Code Online (Sandbox Code Playgroud)
或者作为全局变量的"主"范围:
int arr[10000000]; //on BSS, sie can be very large
int main{
....
}
Run Code Online (Sandbox Code Playgroud)
但我想要更多这个问题.
是否size_t保证足够大以表示任何类型的大小?根据此参考:
size_t可以存储任何类型(包括数组)的理论上可能存在的对象的最大大小。
通常,这是一个可靠的参考,但我在标准的相关部分中找不到任何证明或质疑此主张的内容。
我从 Do Java数组中找到了最大的大小? 数组大小有一个最大限制.
可能是因为它可能耗尽堆空间.是的,我同意这一点.
我无法理解以下内容:
但为什么每个阵列都有这个限制?
如果我有这么大的数组?
为什么不在总体上达到一定的堆空间阈值(总消耗量)时抛出异常,而不是每个数组都有上限?
注意 :
为什么最大数组与本地声明和全局声明不同?
我在一些博客中读到,在本地声明的情况下,我们可以声明的最大数组大小为10 ^ 6,在全局声明的情况下,在10 ^ 7到2*10 ^ 8之间.这是什么原因?