C++:动态内存管理

很久没写

之前有个笑话,是说:几个程序员去餐厅吃饭,那个会把盘子放回原地的一定是C/C++程序员,因为他们要自己清理内存.

好了,来上题目.

编写函数,返回一个动态分配的int的vector.将此vector传递给另一个函数,这个函数读取标准输入,将读入的值保存在vector元素中.再将vector传递给另一个函数.打印读入的值.记得在恰当的时候delete vector.

小心:动态内存管理容易出错

使用new和delete管理动态内存存在三个问题:

  1. 忘记delete内存,会导致内存泄漏,而且不容易发现.
  2. 使用已经释放掉的对象.有时可以检测出这种错误.
  3. 同一块内存释放两次.

相对于发现“罪证”,制造“罪证”显然容易多了。

C++.
image-2150

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*************************************************************************
    > File Name: test.12.6.cpp
    > Author: puruidong
    > Mail: 1@w1520.com
    > Created Time: 2014年07月25日
 ************************************************************************/

#include<iostream>
#include<new>
#include<vector>
using namespace std;

/************************************
 
    编写函数,返回一个动态分配的int的vector.将此vector传递给另一个函数,这个函数读取标准输入,将读入的值保存在vector元素中.再将vector传递给另一个函数.打印读入的值.记得在恰当的时候delete vector.


 *********************************************/

//输出vector中的内容,并释放内存
void outputvector(vector<int>* vec)
{
    cout << "\noutputvector\n" << endl;
    for(const auto &n:*vec)
    {
        cout << n << endl;
    }
    delete vec;//一定要释放内存.
    /*
   
    下面这一行代码是为了避免"空悬指针"的出现而
    添加的.
   
    执行下面这一行代码之后,vec将不能再次使用.
     
     
     */
    vec=nullptr;
    //报错.cout << vec->size() << endl;
}


//获取动态vector.
vector<int>* getve()
{
    vector<int> *vec=new vector<int>;
    return  vec;
}


//接收标准输入.
void inputvector()
{
    vector<int> *vec=getve();
    int pa ;
    cout << "动态内存分配,请输入数字:" << endl;  
    while(cin >> pa)
    {
        vec->push_back(pa);
   }
    outputvector(vec);
}

int main()
{
    inputvector();
    return 0;
}

C++:单词计数

问题

单词计数程序,有序和无序版本.

C++.
image-2147

有序源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*************************************************************************
    > File Name: test.11.39.cpp
    > Author: puruidong
    > Mail: 1@w1520.com
    > Created Time: 2014年07月15日
 ************************************************************************/

#include<iostream>
#include<map>
using namespace std;

/*********************************
 

    单词计数程序,字典序.


 *****************************************/

 int main()
 {
     cout << "单词计数程序,字典序:" << endl;
     map<string,int> map;
     string pa;
     while(cin >> pa)
     {
         ++map[pa];
     }
     cout << "输出计算结果:" << endl;
     for(const auto &s : map)
     {
        cout << s.first << " ------ "  << s.second << endl;
     }
     return 0;
 }

无序源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*************************************************************************
    > File Name: test.11.38.cpp
    > Author: puruidong
    > Mail: 1@w1520.com
    > Created Time: 2014年07月15日
 ************************************************************************/

#include<iostream>
#include<unordered_map>
#include<iterator>
using namespace std;


/*****************************************
 

    用unordered_map重写单词计数程序


 **************************************************/


 int main()
 {
     unordered_map<string,int> map;
     string pa;
     while(cin >> pa)
     {
         ++map[pa];//自增.
     }
    cout << "***********************\n统计结果:\n******************************" << endl;
     for(const auto &s : map)
     {
         cout << s.first << "\t************************\t" << s.second << endl;
     }
     cout << "输出桶的数目:" << map.bucket_count() << endl;
     cout << "最大能容纳的最多的桶的数量:" << map.max_bucket_count() << endl;
     cout << "第1个桶中有多少个元素:" << map.bucket_size(1) << endl;
     cout << "关键字a在哪个桶中:" << map.bucket("a") << endl;
     cout << "每个桶的平均元素数量:" << map.load_factor() << endl;
     cout << "容器试图维护的平均桶大小:" << map.max_load_factor() << endl;
     
     return 0;
 }

C++:一条复杂语句

语句

1
2
3
//map<string,int> word;
 while(cin >> word)
  ++word_word.insert({word,0}).first->second;

C++.
image-2145

解答

  1. word_word.insert({word,0}):将数据插入到map
  2. word_word.insert({word,0}).first:取出返回的pair(示例,pair的第一个元素是一个迭代器,第二个指示是否添加成功)
  3. word_word.insert({word,0}).first->second:节引用此迭代器,也就是map中值的部分.
  4. ++word_word.insert({word,0}).first->second:循环读入输入,向map里面增加值,并对计数器进行累加.

C++:vector保存pair

问题

编写程序,读入string和int的序列,将每个string和int存入一个pair中,pair保存在一个vector中.

C++.
image-2142

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*************************************************************************
    > File Name: test.11.12.cpp
    > Author: puruidong
    > Mail: 1@w1520.com
    > Created Time: 2014年07月01日
 ************************************************************************/

#include<iostream>
#include<vector>
#include<utility>
using namespace std;

/**********************************
 
    编写程序,读入string和int的序列,将每个string和int存入一个pair中,pair保存在一个vector中.

 ***************************************************/

 int main()
 {
     pair<string,int> ps;
     vector<pair<string,int>> vec;
     string pa;
     int re;
     cout << "输入字符[第一个为字符串,第二个必须为数字]:" << endl;
        cin >> pa >> re;
        ps={ pa, re };
   
    vec.push_back(ps);
     for(const auto &s:vec)
     {
         cout << s.first << "------" << s.second << endl;
     }
     return 0;
 }

2:升级版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
[puruidong@localhost 11.2.3]$ cat test.11.13.cpp
/*************************************************************************
    > File Name: test.11.13.cpp
    > Author: puruidong
    > Mail: 1@w1520.com
    > Created Time: 2014年07月01日
**********************/

#include<iostream>
#include<utility>
#include<vector>
using namespace std;


/*********************************
 
 
    编写程序,读入string和int的序列,将每个string和int存入一个pair中,pair保存在一个vector中.
---
修改上述要求,使用至少三种方式创建pair.


***********************************************/


pair<string,int> init1(string s,int a)
{
    pair<string,int> ps(s,a);
    return ps;
}

pair<string,int> init2(string sa,int as)
{
    pair<string,int> psa={sa,as};
    return psa;
}

pair<string,int> init3(string s,int a)
{
    return make_pair(s,a);
}



int main()
{
    vector<pair<string,int>> vec;
    string pa;
    int a;
    cout << "调用第一个方法,请输入,第一个字符串,第二个数字:" << endl;
    cin >> pa >> a;
    vec.push_back(init1(pa,a));
    cout << "调用第二个方法,请输入,第一个字符串,第二个数字:" << endl;
    cin >> pa >> a;
    vec.push_back(init2(pa,a));
    cout << "调用第三个方法,请输入,第一个字符串,第二个数字:" << endl;
    cin >> pa >> a;
    vec.push_back(init3(pa,a));
    for(const auto &s:vec)
    {
        cout << s.first << "######################" << s.second << endl;
    }
    return 0;
}

C++:不重复单词

问题

使用vector和set添加不重复的单词.

C++.
image-2138

源代码

1.使用vector添加不重复的单词.
使用vector添加不重复的单词,比较麻烦,推荐是使用set.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/*************************************************************************
    > File Name: test.11.8.cpp
    > Author: puruidong
    > Mail: 1@w1520.com
    > Created Time: 2014年06月30日
 ************************************************************************/

#include<iostream>
#include<vector>

using namespace std;

/******************************
 

    编写一个程序,在一个vector而不是一个set中保存不重复的单词。使用set的优点是什么.

 *******************************/


 int main()
 {
     vector<string> vec;
     string pa;
     cout << "使用vector保存不重复的单词,请输入单词:" << endl;
     bool check = false ;
     while(cin >> pa)
     {
         check = false;
         for(const auto &v : vec)
         {
             if(v==pa)
             {
                 check=true;
             }
         }
            if(!check)
             {
                 vec.push_back(pa);  
             }
     }
    cout << "***********************************" << endl;
     cout << "下面输出结果:" << endl;
     for(const auto &vc:vec)
     {
         cout << vc << endl;
     }
     return 0;
 }

2.set添加不重复单词.

推荐使用这种方式添加,因为set内保存的本身就属于不重复的元素.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*************************************************************************
    > File Name: test.11.8.1.cpp
    > Author: puruidong
    > Mail: 1@w1520.com
    > Created Time: 2014年06月30日
 ************************************************************************/

#include<iostream>
#include<set>
using namespace std;

/********************************
 
    使用set添加元素.


 ****************************************/


 int main()
 {
     set<string> st;
     cout << "向set添加元素[不可重复]:" << endl;
     string pa;
     while(cin >> pa)
     {
         st.insert(pa);
     }
    cout << "****************************" << endl;
     cout << "下面输出添加的结果:" << endl;
     for(const auto &s:st)
     {
         cout << s << endl;
     }
     return 0;
 }