项目场景:

项目场景:互助群同学在刷题的过程中,遇到的一个题目,需要申请一个很大数组,于是这个同学就写了int[1000000],其实这样写也没有错,可是运行后却显示栈错误。于是就找到我来请教,我想就这个问题延申一下,在谈谈栈空间,堆空间等。

问题描述

#include

int main()

{

int n,s[1000000],max,min,i,j;

long long int sum;

double g;

scanf("%d",&n);

for(i=0;i

{

scanf("%d",&s[i]);

}

max=s[1];min=s[0];

sum=s[0]+s[1];

if(s[0]>s[1])

{

max=s[0];

min=s[1];

}

for(j=2;j

{

if(s[j]>max)

max=s[j];

if(s[j]

min=s[j];

sum=sum+s[j];

g=1.0*(sum-max-min)/(j-1);

printf("%.2lf",g);

}

return 0;

}

这里抛开逻辑不谈,在申请int s[1000000]时,就可能导致越栈空间的问题。许多初学者可能分不太清临时数组和动态数组的区别,所以会一直以来使用int s[1024]这种申请数组的形式,但是一旦申请的内存大就会出问题,这里题目要求10的6次方,就是考察你是否会使用动态申请内存。

解决方案:

我直接给出动态申请内存的代码,这不是我想讲的重点。重点放在原因分析

#include

#include

int main() {

int* arr = (int*)malloc(1000000 * sizeof(int));

if (arr == NULL) {

printf("内存分配失败\n");

return 1;

}

// 现在你可以使用 arr 指针来操作这个动态分配的数组

// 例如,给数组赋值

for (int i = 0; i < 1000000; i++) {

arr[i] = i;

}

// 打印数组中的值

for (int i = 0; i < 1000000; i += 100000) {

printf("%d ", arr[i]);

}

printf("\n");

// 释放动态分配的内存

free(arr);

return 0;

}

原因分析:

计算机的栈空间和堆空间是两种不同的内存分配区域,它们在内存管理和使用方式上有一些重要的区别。

找到一张博主的图很不错转载:http://t.csdnimg.cn/jvgKJ这个博文讲的会很详细,我就不讲那么细了 先看一下两个地址的区别 栈空间(Stack): 栈空间是一种静态内存分配,由编译器自动分配和释放。 栈空间主要用于存储函数的局部变量、函数参数、函数调用的返回地址等。 栈空间的大小是固定的,通常比堆空间小,而且通常不需要手动管理。 栈空间的分配和释放是自动的,遵循“先进后出”的原则,即最后进入的数据最先出来。

堆空间(Heap): 堆空间是一种动态内存分配,需要手动分配和释放。 堆空间主要用于存储动态分配的内存,例如使用 malloc、new 等函数分配的内存。 堆空间的大小不固定,通常比栈空间大,需要手动管理分配和释放。 堆空间的分配和释放需要程序员手动控制,如果没有正确释放分配的内存,可能会导致内存泄漏等问题。

读完之后,你要知道int s[100000]就是在栈空间上找个这么多个连续的int内存准备好给你用,看图上Stack有个小箭头,代表内存向下生长,也就是说你一直无止尽的申请内存,就会往下跑,一旦跑到Memory区域,就会报错,告诉你,我没有内存可以申请使用了(Stack区域是比较小的,比heap小很多)。

讲个题外话,很早以前Stack是向上生长的,一旦到达kernel区域,就是计算机的底层核心代码区域,就可以对地址进行操作,达到控制计算机的目的,黑客也就是这么做的。

所以这个题目需要申请10的6次方,我们需要申请动态内存,而且这一块内存可以反复利用,一旦之前申请的内存free了,再次申请时,这一块内存就可以再度利用了。

好文推荐

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。