c++ 栈溢出问题

发布于:2024-04-17 ⋅ 阅读:(106) ⋅ 点赞:(0)

示例代码:

#include <iostream>
#include <chrono>
#include <fstream>

int main() {
    // 测量内存操作的执行时间
    int num = 1024 * 1024;
    int arry[num] = {2};
    int arry_tmp[num] = {0};

    std::ofstream outfile("data.bin", std::ios::binary | std::ios::out);

    if (!outfile.is_open()) {
        std::cerr << "Failed to open the file." << std::endl;
        // return 1;
    }


    auto start_mem = std::chrono::steady_clock::now();
    // 在这里执行内存操作
    // 例如:循环访问一个大型数组,进行数据处理等
    memcpy(arry_tmp, arry, sizeof(int)*num);
    auto end_mem = std::chrono::steady_clock::now();
    auto mem_duration = std::chrono::duration_cast<std::chrono::microseconds>(end_mem - start_mem);
    std::cout << "Memory operation took: " << mem_duration.count() << " microseconds" << std::endl;

    // 测量IO操作的执行时间
    auto start_io = std::chrono::steady_clock::now();
    // 在这里执行IO操作
    // 例如:读写文件,网络通信等
    outfile.write(reinterpret_cast<const char*>(arry_tmp), sizeof(arry_tmp));
    auto end_io = std::chrono::steady_clock::now();
    auto io_duration = std::chrono::duration_cast<std::chrono::microseconds>(end_io - start_io);
    std::cout << "IO operation took: " << io_duration.count() << " microseconds" << std::endl;

    return 0;
}

输出:

(py37) hq@nuc:~/java/my-project2$ ./a.out 
Segmentation fault (core dumped)

内存检查工具

(py37) hq@nuc:~/java/my-project2$ valgrind ./a.out 
==321460== Memcheck, a memory error detector
==321460== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==321460== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==321460== Command: ./a.out
==321460== 
==321460== Stack overflow in thread #1: can't grow stack to 0x1ffe801000
==321460== 
==321460== Process terminating with default action of signal 11 (SIGSEGV)
==321460==  Access not within mapped region at address 0x1FFE8029E8
==321460== Stack overflow in thread #1: can't grow stack to 0x1ffe801000
==321460==    at 0x109677: main (in /home/hq/java/my-project2/a.out)
==321460==  If you believe this happened as a result of a stack
==321460==  overflow in your program's main thread (unlikely but
==321460==  possible), you can try to increase the size of the
==321460==  main thread stack using the --main-stacksize= flag.
==321460==  The main thread stack size used in this run was 8388608.
==321460== Stack overflow in thread #1: can't grow stack to 0x1ffe801000
==321460== 
==321460== Process terminating with default action of signal 11 (SIGSEGV)
==321460==  Access not within mapped region at address 0x1FFE8019E8
==321460== Stack overflow in thread #1: can't grow stack to 0x1ffe801000
==321460==    at 0x4831134: _vgnU_freeres (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_core-amd64-linux.so)
==321460==  If you believe this happened as a result of a stack
==321460==  overflow in your program's main thread (unlikely but
==321460==  possible), you can try to increase the size of the
==321460==  main thread stack using the --main-stacksize= flag.
==321460==  The main thread stack size used in this run was 8388608.
==321460== 
==321460== HEAP SUMMARY:
==321460==     in use at exit: 80,344 bytes in 178 blocks
==321460==   total heap usage: 178 allocs, 0 frees, 80,344 bytes allocated
==321460== 
==321460== LEAK SUMMARY:
==321460==    definitely lost: 0 bytes in 0 blocks
==321460==    indirectly lost: 0 bytes in 0 blocks
==321460==      possibly lost: 0 bytes in 0 blocks
==321460==    still reachable: 80,344 bytes in 178 blocks
==321460==         suppressed: 0 bytes in 0 blocks
==321460== Rerun with --leak-check=full to see details of leaked memory
==321460== 
==321460== For lists of detected and suppressed errors, rerun with: -s
==321460== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

查看系统限制的栈内存,ulimit -s 命令输出的值是以KB为单位的

blueberry@nuc:~/NT3_panamera/ADB_APP/adb_app$ ulimit -s
8192

正确操作

(py37) hq@nuc:~/java/my-project2$ ulimit -s 16384
(py37) hq@nuc:~/java/my-project2$ ./a.out 
Memory operation took: 595 microseconds
IO operation took: 3958 microseconds

这里也可以看到io耗时的问题:IO操作耗时和内存拷贝耗时比较

内存消耗:无论是栈还是堆,过大的大小都会占用大量的内存资源,可能导致系统的内存不足。

  1. 性能影响:较大的栈或堆大小都可能会影响程序的性能。栈的管理会增加函数调用和返回的成本,堆的动态内存分配和释放也会增加开销。
  2. 潜在问题:过大的栈或堆大小都可能会隐藏程序中存在的一些问题,例如内存泄漏、内存碎片化等。
  3. 调整建议:针对栈和堆的调整建议都是根据程序的实际需求和性能考虑,避免设置过大的大小,以节省内存资源并提高程序性能。

综上所述,栈和堆在内存管理方面有相似之处,都需要根据实际情况进行合理的调整,并注意及时发现和解决可能存在的问题。


网站公告

今日签到

点亮在社区的每一天
去签到