内存问题

c++开发过程中常常遇到内存问题,内存问题也常常是非常棘手的问题。

那么常见的内存问题有哪些呢?

常见的内存问题

常见的一些内存问题包括以下这些。

非法内存访问(Invalid Memory Access)

异常发生在读写了一个没有分配或者已经被析构的内存地址。

Invalid Memory Access
1
2
3
char *pStr = (char*) malloc(25); 
free(pStr);
strcpy(pStr, .parallel programming.); // Invalid write to deallocated memory in heap

内存泄漏(Memory leaks)

内存泄漏发生在分配了内存但是没有释放的场景。

1
2
char *pStr = (char*) malloc(100);
return;

或者

1
2
int *p = new int();
return;

重复释放内存(repeated free)

重复释放内存,就是同一块内存被多次释放了。同样会发生异常。

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

int main()
{
int *p = new int;

printf("fasdfdas \n");

delete(p);
delete(p); // 得到异常打印 free(): double free detected in tcache 2
}

访问了没有初始化的内存(Uninitialized Memory Access)

内存值没有被初始化

1
2
char *pStr = (char*) malloc(512);
char c = pStr[0]; // the contents of pStr were not initialized
1
2
3
4
5
void func()
{
int a;
int b = a * 4; // uninitialized read of variable a
}

为了避免这种情况,应该在使用之前对其进行初始化。

跨栈访问(Cross Stack Access)

多线程访问同一块栈内存

This occurs when a thread accesses stack memory of a different thread.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
main()
{
int *p;
-------
CreateThread(., thread #1, .); // Stack Owned
CreateThread(., thread #2, .);
-------
}
Thread #1
{
int q[1024];
p = q;
q[0] = 1;
}
Thread #2
{
*p = 2; // Stack Cross Accessed
}

要避免在全局变量中存储栈地址。

工具

手动发现内存错误在大型应用程序中是非常困难的,实际工作中常常要借助一些工具来分析内存问题。

Android 常见内存处理手段

查询进程所占用的内存大小

1
adb shell dumpsys meminfo PID

查询占用CPU信息

1
adb shell dumpsys cpuinfo PID

adb shell showmap PID可以看到具体的内存分部情况,进程真正的内存值为PSS+swap PSS.

进程中加载的so不一定都是运行在这个进程的,还有一部分是某个库link过去的,这种so 内存为加载它的进程分摊,所以如果整机进程少了,相同条件下现有进程内存值可能会比较大。

Addr2Line工具

Addr2line 是linux上的一个调试工具,是一个可以将指令的地址和可执行映像转换成文件名、函数名和源代码行数的工具。

Addr2line教程参考

本文参考链接:

  1. https://www.cprogramming.com/tutorial/memory_debugging_parallel_inspector.html


关注博客或微信搜索公众号多媒体与图形,获取更多内容,欢迎在公众号留言交流!
扫一扫关注公众号
作者

占航

发布于

2021-08-30

更新于

2023-10-04

许可协议

评论