C/C++中有关内存问题的汇总

一、C/C++类型大小问题

类型 32位环境下所占字节数 64位环境下所占字节数
char 1 1
short int 2 2
int 4 4
long int 4 8
long long int 8 8
float 4 4
double 8 8
char* 4 4
int * 4 4

特别地,NULL占用4字节。

二、数据存储问题

(一)、C/C++内存中五大区域

其在内存中分配的位置图如下。
内存分布

1、堆(Heap)

存放着由操作malloc/free,new/delete分配/释放的内存(不太安全的内存管理方式)。堆可以动态地扩展和收缩,这个区域通常较大,并向高地址扩展。动态内存的生存期人为决定,使用灵活。缺点是容易造成内存泄漏(Memory Leakage),频繁操作会产生大量内存碎片。

(1)、内存碎片(Memory Fragment)

内存碎片分为两种:外部碎片和内部碎片。

①、外部碎片(External Memory Fragment)

外部碎片指的是还没有被分配出去(不属于任何进程),但由于太小了无法分配给申请内存空间的新进程的内存空闲区域。
外部碎片是出于任何已分配区域或页面外部的空闲存储块。这些存储块的总和可以满足当前申请的长度要求,但是由于它们的地址不连续或其他原因,使得系统无法满足当前申请。
多道可变连续分配只有外部碎片。

②、内部碎片(Internal Memory Fragment)

内部碎片就是已经被分配出去(能明确指出属于哪个进程)却不能被利用的内存空间;
内部碎片是处于区域内部或页面内部的存储块。占有这些区域或页面的进程并不使用这个存储块。而在进程占有这块存储块时,系统无法利用它。直到进程释放它,或进程结束时,系统才有可能利用这个存储块。
单道连续分配只有内部碎片。多道固定连续分配既有内部碎片,又有外部碎片。

③、内存碎片减少的方法(Solutions)

采用控制页边界对齐内存字节对齐、将相邻空闲内存块连接起来、内存池等先进的内存管理机制。

2、栈(Stack)

存放函数的参数值局部变量,函数执行结束时会被自动释放。栈内存分配运算内置于处理器的指令集中,效率高,但是容量有限。(栈方便用来保存/恢复调用现场,可以把其看成一个暂时保存和交换数据的区域)

3、BSS段(Block Started by Symbol Segment)

用来存放程序未初始化的全局变量。不保存在硬盘上,只是记录数据所需空间的大小,程序开始执行之前,由内核进行初始化为0。BSS段属于静态内存分配,即程序一开始就将其清零了。

4、数据段(Data Segment)

用来存放程序已初始化的全局变量。数据段属于静态内存分配。其中static静态变量存放在数据段中,而非栈区。

5、代码段(Code Segment/Text Segment)

用来存放程序执行代码。这部分区域的大小在程序运行前就已经确定,通常为只读(某些架构也允许代码段为可写,即允许修改程序),也有可能包含一些只读的常量,例如字符串常量等。

三、结构体和数组的问题

如下所示,假如系统的数据存储方式为小端模式(Little Endian),三个输出应该是什么?

#include <iostream>

struct data {
       uint16_t a;
       uint8_t b;
       uint16_t c;
}*example;

int main(int argc, char* argv[]) {
       uint8_t num[] = { 1,2,3,4,5,6,7 };
       example =(struct data*)num;
       printf("%x %x %x", example->a, example->b, example->c);
       system("pause");
       return 0;
}

输出结构是 0x0201 0x03 0x0605,这是为什么呢?看下面的数据存放图。

在这里插入图片描述

可以得出结构体中16位的a等于0x0201,8位的b等于0x03,16位的c等于0x0605。由于内存对齐,成员b只用到了低字节0x03,0x04就被舍弃了(实际上还存在内存里,但用不到,除非在b的地址加上一字节偏移,如使用*(&(example->b)+1) 就能读到0x04)。

参考链接:
C/C++内存分配方式与存储区

发布了81 篇原创文章 · 获赞 7 · 访问量 2万+
展开阅读全文

c++内存问题!!!!!!!

05-27

#include <iostream> #include <string> #include <vector> using namespace std; int main() { string a, b; int i, x, y; vector<string> v1, v2; while (cin >> a >> b) { for (i = 0; i < v1.size(); i++) { if (v1[i] == a) { x = i; break; } } if (i == v1.size()) x = i; for (i = 0; i < v2.size(); i++) { if (v2[i] == b) { y = i; break; } } if (i == v2.size()) y = i; if (x == v1.size() && y == v2.size()) { cout << b << " registered." << endl; v1.push_back(a); v2.push_back(b); } else if (v1[y] == a && v2[x] == b) { cout << b << " signed in." << endl; } else if (x != v1.size() && y == v2.size()) { cout << "GOTCHA: MAC address already occupied by "; cout << v2[x] << "." << endl; } else { cout << "GOTCHA: " << b << " MAC address not consistent." << endl; } } return 0; } Invalid read of size 8 | at 0x3F8CC9C0D0: std::string::size() const (in /usr/lib64/libstdc++.so.6.0.13) | by 0x40175D: __gnu_cxx::__enable_if<std::__is_char<char>::__value, bool>::__type std::operator==<char>(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:2243) | by 0x4012B5: main (main.cpp:30) | Address 0x4c29498 is 8 bytes before a block of size 8 alloc'd | at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298) | by 0x402184: __gnu_cxx::new_allocator<std::string>::allocate(unsigned long, void const*) (new_allocator.h:89) | by 0x401F80: std::_Vector_base<std::string, std::allocator<std::string> >::_M_allocate(unsigned long) (stl_vector.h:140) | by 0x401BBB: std::vector<std::string, std::allocator<std::string> >::_M_insert_aux(__gnu_cxx::__normal_iterator<std::string*, std::vector<std::string, std::allocator<std::string> > >, std::string const&) (vector.tcc:322) | by 0x401877: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:741) | by 0x40122E: main (main.cpp:27) | |Invalid read of size 8 | at 0x3F8CC9C0D3: std::string::size() const (in /usr/lib64/libstdc++.so.6.0.13) | by 0x40175D: __gnu_cxx::__enable_if<std::__is_char<char>::__value, bool>::__type std::operator==<char>(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:2243) | by 0x4012B5: main (main.cpp:30) | Address 0xffffffffffffffe8 is not stack'd, malloc'd or (recently) free'd | | |Process terminating with default action of signal 11 (SIGSEGV) | Access not within mapped region at address 0xFFFFFFFFFFFFFFE8 | at 0x3F8CC9C0D3: std::string::size() const (in /usr/lib64/libstdc++.so.6.0.13) | by 0x40175D: __gnu_cxx::__enable_if<std::__is_char<char>::__value, bool>::__type std::operator==<char>(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:2243) | by 0x4012B5: main (main.cpp:30) | If you believe this happened as a result of a stack | overflow in your program's main thread (unlikely but | possible), you can try to increase the size of the | main thread stack using the --main-stacksize= flag. | The main thread stack size used in this run was 10485760. |66 bytes in 2 blocks are possibly lost in loss record 3 of 4 | at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298) | by 0x3F8CC9C3C8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.13) | by 0x3F8CC9D19A: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib64/libstdc++.so.6.0.13) | by 0x3F8CC9D5EB: std::string::reserve(unsigned long) (in /usr/lib64/libstdc++.so.6.0.13) | by 0x3F8CC7B05A: std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (in /usr/lib64/libstdc++.so.6.0.13) | by 0x401431: main (main.cpp:8) | |114 bytes in 2 blocks are possibly lost in loss record 4 of 4 | at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298) | by 0x3F8CC9C3C8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.13) | by 0x3F8CC9D19A: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib64/libstdc++.so.6.0.13) | by 0x3F8CC9D5EB: std::string::reserve(unsigned long) (in /usr/lib64/libstdc++.so.6.0.13) | by 0x3F8CC7B05A: std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (in /usr/lib64/libstdc++.so.6.0.13) | by 0x40141F: main (main.cpp:8) 怎么破! 求大神 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 游动-白 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览