【c语言】重温一下动态内存,int数组过大会造成栈错误

这篇具有很好参考价值的文章主要介绍了【c语言】重温一下动态内存,int数组过大会造成栈错误。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

项目场景:

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


问题描述

#include<stdio.h>
int main()
{
 int n,s[1000000],max,min,i,j;
 long long int sum;
 double g;
 scanf("%d",&n);
 for(i=0;i<n;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<n;j++)
 {
  if(s[j]>max)
   max=s[j];
  if(s[j]<min)
   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 <stdio.h>
#include <stdlib.h>

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;
}

原因分析:

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

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

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

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

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

所以这个题目需要申请10的6次方,我们需要申请动态内存,而且这一块内存可以反复利用,一旦之前申请的内存free了,再次申请时,这一块内存就可以再度利用了。文章来源地址https://www.toymoban.com/news/detail-758321.html

到了这里,关于【c语言】重温一下动态内存,int数组过大会造成栈错误的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 超详细——动态内存分配+柔性数组

    ☃️个人主页:fighting小泽 🌸作者简介:目前正在学习C语言和数据结构 🌼博客专栏:C语言学习 🏵️欢迎关注:评论👊🏻点赞👍🏻留言💪🏻 我们已经学会的内存开辟方式有:创建一个变量,创建一个数组 我们创建一个整形变量就会申请4个字节,创建个数组就会申请

    2023年04月15日
    浏览(19)
  • C语言 — 动态内存管理(动态内存函数)

    本期分为三篇介绍动态内存管理相关内容,关注博主了解更多 博主博客链接:https://blog.csdn.net/m0_74014525 本期介绍动态内存函数,函数如何使用、函数格式、在使用在所需要的注意点及C/C++程序的内存开辟区域 第一篇:C语言 — 动态内存管理(动态内存函数) 第二篇:C语言

    2024年02月14日
    浏览(24)
  • C语言:动态内存(一篇拿捏动态内存!)

    目录 学习目标:  为什么存在动态内存分配  动态内存函数: 1. malloc 和 free 2. calloc 3. realloc 常见的动态内存错误: 1. 对NULL指针的解引用操作 2. 对动态开辟空间的越界访问 3. 对非动态开辟内存使用free释放 4. 使用free释放一块动态开辟内存的一部分 5. 对同一块动态内存多次

    2024年02月10日
    浏览(25)
  • 柔性数组和C语言内存划分

    也许你从来没有听说过 柔性数组 (flexible array)这个概念,但是它确实是存在的。 C99 中,结构中的最后⼀个元素允许是未知大小的数组,这就叫做『柔性数组』成员。 例如: 有些编译器会报错⽆法编译可以改成: 1.1 柔性数组的特点: 结构中的柔性数组成员前面必须至少⼀

    2024年01月22日
    浏览(17)
  • C语言动态内存练习:【通讯录(动态内存版本)实现】

    前面我们写了一个静态数组版本的通讯录,再结合刚学习的动态内存管理的知识,我们现在来实现一个动态内存版本的通讯录。 动态内存版本的通讯录,主要还是为了解决静态数组版本的通讯录空间太大导致的内存浪费和空间太小不够存放的问题。 扩容策略: 为通讯录设置

    2023年04月13日
    浏览(48)
  • 「探索C语言内存:动态内存管理解析」

    🌠先赞后看,不足指正!🌠 🎈这将对我有很大的帮助!🎈 📝所属专栏:C语言知识 📝阿哇旭的主页:Awas-Home page 目录   引言 1. 静态内存 2. 动态内存 2.1 动态内存开辟函数 2.1.1 malloc函数 2.1.2 calloc函数 2.1.3 realloc函数 2.2 动态内存释放函数 2.2.1 free函数 3. 动态内存的常见

    2024年04月28日
    浏览(18)
  • 探索C语言的内存魔法:动态内存管理解析

    ✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C语言学习 贝蒂的主页:Betty‘s blog 通过前面的学习,我们已经掌握了两种开辟内存的方法,分别是: 但是静态开辟的空间明显有两个缺陷: 空间开辟⼤⼩是 固定 的。 数组在申明的时候,

    2024年02月19日
    浏览(23)
  • C语言:动态内存管理

    先点赞再观看哦! 学习数据结构之前,一定要对指针、结构体、动态内存管理进行深入学习! 小伙伴们可以看看博主之前的文章! 今天重点介绍动态内存开辟!十分重要哈! 我们已知的内存开辟方式有什么呢?? 但是上述开辟的空间有三个特点: 1、空间开辟的大小是固定

    2024年01月22日
    浏览(22)
  • 【C语言:动态内存管理】

    文章的标题是动态内存管理,那什么是动态内存管理?为什么有动态内存管理呢? 回顾一下以前学的知识,我们已经掌握的开辟内存的方式有以下几种: 上述开辟内存的方式有几个弊端: 开辟空间的大小是固定的 数组在声明的时候,必须指定数组的长度,数组空间⼀旦确定

    2024年02月03日
    浏览(21)
  • 动态内存管理 --- C语言

    目录 1.为什么存在动态内存管理 2.动态内存函数的介绍 2.1 malloc 与 free  2.2 calloc 2.3 realloc 3.常见的动态内存错误 4.几个经典笔试题 6.柔性数组 我们已经掌握的内存开辟方式有: 但是上述的开辟空间的方式有两个特点: 空间开辟的 大小是固定的 。 数组在声明的时候, 必须指

    2024年02月11日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包