Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.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
在C中初始化16mb数组_C_Arrays_Segmentation Fault_Malloc_Heap - Fatal编程技术网

在C中初始化16mb数组

在C中初始化16mb数组,c,arrays,segmentation-fault,malloc,heap,C,Arrays,Segmentation Fault,Malloc,Heap,我对“C”比较陌生,希望能对这个话题有所了解 基本上,我正在尝试创建一个16 MB的数组,并检查内存内容是否初始化为零或“\0”或某个学校项目的垃圾值 大概是这样的: char缓冲区[16*1024*1024] 我知道程序堆栈的大小是有限制的,显然我遇到了分段错误。是否可以使用malloc()以某种方式完成此操作?当然: int memSize = 16*1024*1024; char* buffer = malloc( memSize ); if ( buffer != 0 ) { /

我对“C”比较陌生,希望能对这个话题有所了解

基本上,我正在尝试创建一个16 MB的数组,并检查内存内容是否初始化为零或“\0”或某个学校项目的垃圾值

大概是这样的:

char缓冲区[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 );
}
int memSize=16*1024*1024;
char*buffer=malloc(memSize);
如果(缓冲区!=0)
{
//检查内容
对于(i=0;i
您可以使用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
}
然后,您可以检查内存中的值,以便(注意,这将打印很长时间):


是的,您可能需要使用
malloc()
执行此操作,原因如下:

当任何程序(进程…线程…)启动时,都会给它一块内存,用于存储(除其他外…“本地”变量)。这个区域被称为“堆栈”,它肯定不会大到足以存储16兆字节

但是,任何程序都可以使用另一个内存区域:它的“堆”。这个区域(顾名思义,“堆”)没有固有的结构:它只是一个存储池,通常足够大,可以存储很多兆字节。您只需
malloc()
所需的字节数,并在完成后
free()
这些字节

只需定义一个与需要存储的结构相对应的
type
,然后
malloc(sizeof(type))
。存储将来自堆。(基本上,这就是堆的用途……)


顺便提一下,有一个名为
calloc()
的库函数,它将保留一个“已知零”的区域。此外,它可能会使用巧妙的操作系统技巧来非常有效地执行此操作。

严格地说,代码无法检查
缓冲区是否未归零,而不会导致未定义的行为。如果类型是
无符号字符
,则没有问题。但是可能有符号的
char
,可能有一个陷阱值。尝试使用该值将导致UB

char buffer[16*1024*1024];
// Potential UB
if (buffer[0])  ...
最好使用不能有陷阱值的
无符号字符

#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;
定义N(16LU*1204*1204) 无符号字符*buffer=malloc(N); if(缓冲区){
对于(size_t i=0;如果用户是C的“新手”,您可能应该包括一个free示例。您的代码会检查缓冲区是否已归零,而不存在UB风险,因此需要编辑第一句话。此外,C11表示可以通过字符类型读取陷阱表示,因此我认为
char*
版本是正确的OK@MattMcNabb扫描C11并且没有清楚地看到一个
char
trap的位置。任何细节都很好。@Matt McNabb,可能会有用。短期内。以后需要深入研究C11。C99+TC2(N1124)和C11都清楚地表示在6.2.6.1/5中,如果对象的存储值具有这样的表示形式,并且由没有字符类型的左值表达式读取,则该行为是未定义的。“因此,
char
是否有陷阱表示并不重要;即使有,读取它们也不会导致UB。尽管我想你可能会争辩说,它也没有说明当
char
的陷阱表示被读取时会发生什么,任何未定义的内容都是未定义的。C11在子句中添加“
有符号字符
不得有任何填充位"。它仍然可以有陷阱表示负零,所以我用6.2.6.1/5来说明读取负零本身不会导致UB;但是我们参考6.2.6.2中关于负零的规则,看看随后对值执行的操作是否会触发UB。我们必须显式释放这个分配的内存吗?我想t当程序执行完毕后,内存会自动释放回操作系统。如果我错了,请纠正我。是的,在这种情况下,但通常这样做是很好的做法。对于任何非琐碎的代码,程序通常会运行一段时间,因此:1 malloc=1 free。因为OP对C来说显然是新的,最好立即开始正确的轨道<代码>printf(“\nAddr:0x%08x:”,(无符号int)(&buffer[i]))
警告:从指针强制转换为不同大小的整数。使用%p更方便吗?@Absolut\u Red:是的,这是一个更好的方法。我将进行编辑以反映这一点。“0x”前缀也会加倍。如果可以忽略这一点,请注意:今天许多系统使用32位
int
,因此
16*1024*1024
不是问题。注意一些问题16位
int
仍然存在且
16*1024*1024
溢出的CPU(如某些嵌入式设备)。代码可以使用
16L*1024*1024
(添加了L)当然,在16位
int
设备上不太可能使用16 MB数组。@chux:你能详细说明一下“L”代表什么吗?它的一般用途吗?那太好了。
L
使一个常量至少type
long
long
整数的范围至少在-2000000到+2000,0之间00000范围。(-power(2,31)+1…power(2,31)-1)。
char buffer[16*1024*1024];
// Potential UB
if (buffer[0])  ...
#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;