开发者社区> 王小闹儿> 正文

利用动态规划算法解01背包问题->二维数组传参->cpp内存管理->堆和栈的区别->常见的内存错误及其对策->指针和数组的区别->32位系统是4G

简介: 1、利用动态规划算法解01背包问题 https://www.cnblogs.com/Christal-R/p/Dynamic_programming.html 两层for循环,依次考察当前石块是否能放入背包。
+关注继续查看

1、利用动态规划算法解01背包问题

https://www.cnblogs.com/Christal-R/p/Dynamic_programming.html

两层for循环,依次考察当前石块是否能放入背包。如果能,则考察放入该石块是否会得到当前背包尺寸的最优解。

// 01 knapsack problem dynamic programming algorithm

#include "pch.h"
#include <iostream>

void dynamic_program( int stone_num, int knapsack_capacity, int stone_weight[],  
	int stone_value [], int stone_in_or_not [], int (*V)[8]) {

	//栈内存需要初始化
	memset(V, 0, sizeof(V));

	for (int i = 0; i < stone_num; i++) {
		for (int j = 1; j <= knapsack_capacity; j++) {
			//此时背包无法装入当前石块
			if (j < stone_weight[i]) {
				V[i][j] = V[i - 1][j];
			}
			else {
				//不装入价值更大
				if (V[i - 1][j] > (V[i - 1][j - stone_weight[i]] + stone_value[i])) {
					V[i][j] = V[i - 1][j];
				}
				else {
					//前i-1个物品的最优解与第i个物品的价值之和最大
					V[i ][j] = (V[i - 1][j - stone_weight[i]] + stone_value[i]);
					stone_in_or_not[i] = 1;
				}
			}
		}
	}
	int a = 0;
}
void init() {
	int stone_num = 4, knapsack_capacity = 8;
	int stone_weight[] = { 2, 3, 4, 5 };
	int stone_value[] = { 3, 4, 5, 6 };
	int stone_in_or_not[] = { 0,0,0,0,0,0,0,0 };
	int V[4][8];
	dynamic_program(stone_num, knapsack_capacity, stone_weight, stone_value, stone_in_or_not, V);

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

 

2、二维数组传参

https://blog.csdn.net/yunyun1886358/article/details/5659851

int main()
{
    int m = 10;
    int n = 10;
    int** p = new int[m][n];
}

会发现编译不通过,第二个维度长度必须为常量。那么怎么声明一个两个维度都能动态指定的二维数组呢?看下面:

void func5(int** pArray, int m, int n)
{

}

#include <ctime>
int main()
{
    int m = 10;
    int n = 10;

    int** pArray = new int* [m];
    pArray[0] = new int[m * n]; // 分配连续内存

    // 用pArray[1][0]无法寻址,还需指定下标寻址方式
    for(int i = 1; i < m; i++)
    {
        pArray[i] = pArray[i-1] + n;
    }

    func5(pArray, m, n);
}

这里为二维数组申请了一段连续的内存,然后给每一个元素指定寻址方式(也可以为每一个元素分别申请内存,就不必指定寻址方式了),最后将双重指针作为实参传递给func5。这里func5多了两个形参,是二维数组的维度

 

3、堆和栈的区别

主要区别有以下几点

(1)管理方式不同(2)空间大小不同(3)能否产生碎片不同(4)生长方式不同

(5)分配方式不同(6)分配效率不同

 

4、常见的内存错误及其对策

(1)内存分配未成功,却使用了它。因为内存分配会不成功。

常用解决办法是,在使用内存之前检查指针是否为NULL。

如果指针p是函数的参数,那么在函数的入口处用assert(p!=NULL)进行检查。

如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。

(2)内存分配虽然成功,但是尚未初始化就引用它。

内存的缺省初值究竟是什么并没有统一的标准,尽管有些时候为零值,我们宁可信其无不可信其有。所以无论用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略,不要嫌麻烦。

(3)内存分配成功并且已经初始化,但操作越过了内存的边界。

例如在使用数组时经常发生下标“多1”或者“少1”的操作。特别是在for循环语句中,循环次数很容易搞错,导致数组操作越界。

(4)忘记了释放内存,造成内存泄露。

含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足,你看不到错误。终有一次程序突然死掉,系统出现提示:内存耗尽。动态内存的申请与释放必须配对,程序中malloc与free的使用次数一定要相同,否则肯定有错误(new/delete同理)。

(5)释放了内存却继续使用它。发生该情况有三种可能:

1). 程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。

2). 函数的return语句写错了,注意不要返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。

3). 使用free或delete释放了内存后,没有将指针设置为NULL。导致产生“野指针”

那么如何避免产生野指针呢?这里列出了5条规则,平常写程序时多注意一下,养成良好的习惯。

规则1:用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。

规则2:不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。

规则3:避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。

规则4:动态内存的申请与释放必须配对,防止内存泄漏。

规则5:用free或delete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。

 

5、指针和数组的区别

下面示例中,字符数组a的容量是6个字符,其内容为 hello。a的内容可以改变,如a[0]= ‘X’。指针p指向常量字符串“world”(位于静态存储区,内容为world),常量字符串的内容是不可以被修改的。从语法上看,编译器并不觉得语句p[0]= ‘X’有什么不妥,但是该语句企图修改常量字符串的内容而导致运行错误。

 

6、32位系统是4G

https://blog.csdn.net/nvd11/article/details/8749375

 

7、各种getmemory

https://blog.csdn.net/u010027547/article/details/52292889

 

参考文献:

assert()函数 :  https://www.cnblogs.com/lvchaoshun/p/7816288.html

cpp内存管理:  https://chenqx.github.io/2014/09/25/Cpp-Memory-Management/

二维数组传参:  https://blog.csdn.net/yunyun1886358/article/details/5659851

动态规划算法解决01背包问题: https://www.cnblogs.com/Christal-R/p/Dynamic_programming.html

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
海量数据处理面试题:给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?
海量数据处理面试题:给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?
22 0
32位操作系统单进程最大使用4G内存
有此疑问的原因:在看jvm书籍时,碰到了介绍“直接内存”的内容,直接内存不是虚拟机运行时数据区的一部分,所以也就不是jvm名义上管理的部分,同时《java虚拟机规范》也未对其定义,但是这块区域也会被经常使用。这块区域使用的是计算机本身的内存,那么就需要考虑在给jvm各个区域提供参数时各个值的大小了,比如32位操作系统中,单进程最大可用4G的内存,如果jvm中各个区域占用内存很接近4G的话,就可能导致直接内存这块产生OOM(直接内存区域也会有OOM产生,这里不说原因了)。
37 0
STM32的内存管理相关(内存架构,内存管理,map文件分析)
STM32 的内存架构,内存管理以及 map 文件分析
163 0
JavaScript的内存和内存管理
JavaScript的内存和内存管理
67 0
SAP专家培训之Netweaver ABAP内存管理和内存调优最佳实践
SAP专家培训之Netweaver ABAP内存管理和内存调优最佳实践
92 0
JVM内存管理、直接内存和垃圾回收
无论对于Java程序员还是大数据研发人员,JVM是必须掌握的技能之一。既是面试中经常问的问题,也是在实际业务中对程序进行调优、排查类似于内存溢出、栈溢出、内存泄漏等问题的关键
445 0
Java的内存 -JVM 内存管理
一.综述 如果你学过C或者C++,那么你应该感受过它们对内存那种强大的掌控力。但是强大的能力往往需要更强大的控制力才能保证能力不被滥用,如果滥用C/C++的内存管理那么很容易出现指针满天飞的情况,不出问题还好,一出问题debug起来简直让人头疼得不要不要的。
872 0
4核CPU 4G内存 500G硬盘 8M宽带 这样的配置 要租赁云服务器 一年费用大概多少
4核CPU 4G内存 500G硬盘 8M宽带 这样的配置 要租赁云服务器 一年费用大概多少 在阿里云官网上有,可以自动计算价格的。 你按照如下链接选择配置,系统会自动结算哈 https://s.
3163 0
+关注
王小闹儿
应届c++
文章
问答
视频
文章排行榜
最热
最新
相关电子书
更多
云服务器ECS内存增强型实例re6全新发布
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载