在 C 中初始化一个 16mb 的数组
Initialize a 16mb array in C
我对 'C' 比较陌生,希望对这个主题有一些见解。
基本上,我正在尝试创建一个 16 MB 的数组并检查内存内容是否初始化为零或“\0”或学校项目的一些垃圾值。
像这样:
char buffer[16*1024*1024];
我知道程序堆栈的大小是有限制的,显然我遇到了分段错误。可以使用 malloc() 以某种方式完成吗?
当然可以:
int memSize = 16*1024*1024;
char* buffer = malloc( memSize );
if ( buffer != 0 )
{
// check contents
for ( i = 0; i < memSize; i++ )
{
if ( buffer[i] != 0 )
{
// holler
break;
}
}
free( buffer );
}
您可以像这样使用 malloc 初始化内存:
#define MEM_SIZE_16MB ( 16 * 1024 * 1024 )
char *buffer = malloc(MEM_SIZE_16MB * sizeof(char) );
if (buffer == NULL ) {
// unable to allocate memory. stop here or undefined behavior happens
}
然后您可以检查内存中的值(请注意,这将打印很长时间):
for (int i = 0; i < MEM_SIZE_16MB; i++) {
if( i%16 == 0 ) {
// print a newline and the memory address every 16 bytes so
// it's a little easier to read
printf("\nAddr: %08p: ", &buffer[i]);
}
printf("%02x ", buffer[i]);
}
printf("\n"); // one final newline
完成后不要忘记释放内存
free(buffer);
是的,您可能需要使用 malloc()
执行此操作,原因如下:
当任何程序 (process ... thread ...) 启动时,它会获得一块内存,用于存储 (其中其他事情...) "local" 变量。这个区域叫做"the stack."它肯定不够大,无法存储 16 兆字节。
但是还有 另一个 内存区域可供任何程序使用:它的“堆”。这个区域(顾名思义,"heap,"意在暗示...)没有内在的结构:它只是一个存储池,通常足够大,可以存储很多兆字节。您只需 malloc()
您需要的字节数,然后 free()
那些字节。
简单定义一个type
对应你需要存储的结构,然后malloc(sizeof(type))
。存储将来自堆。 (基本上,堆就是 for ...)
顺便说一下,有一个名为 calloc()
的库函数会保留一个区域 "known zero." 此外,它可能会使用巧妙的操作系统技巧来非常有效地做到这一点。
严格来说,代码无法在不冒未定义行为风险的情况下检查 buffer
是否未归零。如果类型是 unsigned char
,那么没问题。但是char
,可能有符号,可能有陷阱值。尝试使用该值会导致 UB。
char buffer[16*1024*1024];
// Potential UB
if (buffer[0]) ...
最好使用不能有陷阱值的 unsigned char
。
#define N (16LU*1204*1204)
unsigned char *buffer = malloc(N);
if (buffer) {
for (size_t i = 0; i<N; i++) {
if (buffer[i]) Note_NonZeroValue();
}
}
// Clean-up when done.
free(buffer);
buffer = 0;
C 的棘手之处在于,即使 char
没有陷阱值,一些聪明的编译器也可以识别代码正在尝试执行符合规范的 UB 然后将 if (buffer[0])
优化为 nothing。禁止读取未初始化的非 unsigned char
数据。
我对 'C' 比较陌生,希望对这个主题有一些见解。
基本上,我正在尝试创建一个 16 MB 的数组并检查内存内容是否初始化为零或“\0”或学校项目的一些垃圾值。
像这样:
char buffer[16*1024*1024];
我知道程序堆栈的大小是有限制的,显然我遇到了分段错误。可以使用 malloc() 以某种方式完成吗?
当然可以:
int memSize = 16*1024*1024;
char* buffer = malloc( memSize );
if ( buffer != 0 )
{
// check contents
for ( i = 0; i < memSize; i++ )
{
if ( buffer[i] != 0 )
{
// holler
break;
}
}
free( buffer );
}
您可以像这样使用 malloc 初始化内存:
#define MEM_SIZE_16MB ( 16 * 1024 * 1024 )
char *buffer = malloc(MEM_SIZE_16MB * sizeof(char) );
if (buffer == NULL ) {
// unable to allocate memory. stop here or undefined behavior happens
}
然后您可以检查内存中的值(请注意,这将打印很长时间):
for (int i = 0; i < MEM_SIZE_16MB; i++) {
if( i%16 == 0 ) {
// print a newline and the memory address every 16 bytes so
// it's a little easier to read
printf("\nAddr: %08p: ", &buffer[i]);
}
printf("%02x ", buffer[i]);
}
printf("\n"); // one final newline
完成后不要忘记释放内存
free(buffer);
是的,您可能需要使用 malloc()
执行此操作,原因如下:
当任何程序 (process ... thread ...) 启动时,它会获得一块内存,用于存储 (其中其他事情...) "local" 变量。这个区域叫做"the stack."它肯定不够大,无法存储 16 兆字节。
但是还有 另一个 内存区域可供任何程序使用:它的“堆”。这个区域(顾名思义,"heap,"意在暗示...)没有内在的结构:它只是一个存储池,通常足够大,可以存储很多兆字节。您只需 malloc()
您需要的字节数,然后 free()
那些字节。
简单定义一个type
对应你需要存储的结构,然后malloc(sizeof(type))
。存储将来自堆。 (基本上,堆就是 for ...)
顺便说一下,有一个名为 calloc()
的库函数会保留一个区域 "known zero." 此外,它可能会使用巧妙的操作系统技巧来非常有效地做到这一点。
严格来说,代码无法在不冒未定义行为风险的情况下检查 buffer
是否未归零。如果类型是 unsigned char
,那么没问题。但是char
,可能有符号,可能有陷阱值。尝试使用该值会导致 UB。
char buffer[16*1024*1024];
// Potential UB
if (buffer[0]) ...
最好使用不能有陷阱值的 unsigned char
。
#define N (16LU*1204*1204)
unsigned char *buffer = malloc(N);
if (buffer) {
for (size_t i = 0; i<N; i++) {
if (buffer[i]) Note_NonZeroValue();
}
}
// Clean-up when done.
free(buffer);
buffer = 0;
C 的棘手之处在于,即使 char
没有陷阱值,一些聪明的编译器也可以识别代码正在尝试执行符合规范的 UB 然后将 if (buffer[0])
优化为 nothing。禁止读取未初始化的非 unsigned char
数据。