- 浏览: 1563053 次
- 性别:
- 来自: 吉林
文章分类
- 全部博客 (624)
- C/C++ (33)
- Java (181)
- 网络相关 (7)
- 我爱篮球 (3)
- 也爱足球 (4)
- 杂谈 (1)
- 系统架构 (3)
- Web Service (14)
- Framework (3)
- 系统命令 (8)
- 管理平台相关 (8)
- 其它 (35)
- Websphere (1)
- Struts2 (24)
- Hibernate (16)
- Spring (23)
- javascript (20)
- jquery (23)
- html/css/div (28)
- 数据库 (40)
- JavaWeb (27)
- 设计模式 (2)
- 文档编写 (3)
- SVN (5)
- Ant (1)
- Maven (13)
- 软件项目管理 (8)
- AOP (1)
- kindeditor (1)
- JSON (2)
- Servlt/JSP (4)
- WordXML (2)
- XML (12)
- 面试相关 (7)
- Tomcat (11)
- 性能与调优 (29)
- 职业发展 (2)
- 操作系统 (7)
- AJAX (2)
- DWR (1)
- Eclipse (12)
- 持续集成 (3)
- 批处理命令 (1)
- Mozilla Rhino (2)
- 新鲜技术 (18)
- Apache mina (2)
- 底层技术 (18)
- Linux (22)
- 新鲜技术,IT历史 (1)
- 敏捷开发 (1)
- 版本控制 (5)
- 较火技术 (7)
- 集群 (2)
- Web前端 (13)
- 报表工具 (3)
- 网站架构 (5)
- 大数据 (8)
- 分布式存储 (5)
- 云计算 (8)
- TCP/IP协议 (1)
- 负载均衡 (3)
- 硬件 (1)
- 表现层技术 (3)
- Velocity (3)
- jvm (6)
- 并发编程 (10)
- hadoop (8)
- 数据结构和算法 (12)
- 计算机原理 (1)
- 测试驱动开发-TDD (3)
- 开发技巧 (1)
- 分词器 (1)
- 项目构建工具 (2)
- JMX (4)
- RMI (1)
- 测试技术 (22)
- 网络完全 (1)
- Git (4)
- apache开源包 (4)
- Java常用 (1)
- mock (2)
- OSGi (2)
- MongoDB (1)
- JBPM (1)
- Storm (3)
- mysql (2)
- telnet (1)
- 正则表达式 (1)
- bootstrap (4)
- Apache ActiveMQ (1)
- redis (9)
- Nginx (2)
- rsync+inotify文件同步 (2)
- testng (1)
- 原型设计工具 (1)
- 工程能力 (1)
- 风险控制 (3)
- ibatis (1)
- 分布式 (4)
- 安全技术 (1)
- 计算机基础 (4)
- 消息中间件 (1)
- UML (2)
最新评论
-
u012236967:
java命令执行jar包(里面的main函数)的方式(包括依赖其它的jar包问题) -
世界尽头没有你:
Selenium自动化测试从入门到精通(Java版)百度网盘地 ...
自动化测试工具 Selenium WebDriver 入门教程(针对主流浏览器) -
小小西芹菜:
我喜欢代码简洁易读,服务稳定的推送服务,前段时间研究了一下go ...
dwr实现Reverse Ajax推送技术的三种方式 -
hellozhouqiao:
楼主,请教一点问题.现在我们需要在excel 的页脚里面加上图 ...
FreeMaker + xml 导出word(处理目录,图片和页眉页脚问题) -
乱在长安:
使用Timer会有各种各样的问题好嘛?!书上推荐使用Sched ...
DelayQueue (ScheduledThreadPoolExecutor调度的实现)
内存的分配何管理一直让许多c++爱好者头痛不已,不仿看看下面的东西!
来自林锐的《高质量c++编程指南》
指针参数是如何传递内存的?
如果函数的参数是一个指针,不要指望用该指针去申请动态内存。示例7-4-1中,Test函
数的语句GetMemory(str, 200)并没有使str获得期望的内存,str依旧是NULL,为什么?
void GetMemory(char *p, int num)//zbf:感觉非常隐蔽,设计错误
{
p = (char *)malloc(sizeof(char) * num);
}
|
void Test(void)
{
char *str = NULL;
GetMemory(str, 100); // str
仍然为 NULL
strcpy(str, "hello"); //
运行错误
}
|
示例7-4-1 试图用指针参数申请动态内存
毛病出在函数GetMemory中。编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,编译器使 _p = p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。在本例中,_p申请了新的内存,只是把_p所指的内存地址改变了,但是p丝毫未变。所以函数GetMemory并不能输出任何东西。事实上,每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。(注意其原理解释)
如果非得要用指针参数去申请内存,那么应该改用“指向指针的指针”,见示例7-4-2。
void GetMemory2(char **p, int num)
{
*p = (char *)malloc(sizeof(char) * num);
} |
void Test2(void)
{
char *str = NULL;
GetMemory2(&str, 100); //
注意参数是 &str,而不是str
strcpy(str, "hello");
cout<< str << endl;
free(str);
}
|
示例7-4-2用指向指针的指针申请动态内存
由于“指向指针的指针”这个概念不容易理解,我们可以用函数返回值来传递动态内存。这种方法更加简单,见示例7-4-3。
char *GetMemory3(int num)
{
char *p = (char *)malloc(sizeof(char) * num);
return p;
} |
void Test3(void)
{
char *str = NULL;
str = GetMemory3(100);
strcpy(str, "hello");
cout<< str << endl;
free(str);
}
|
示例7-4-3 用函数返回值来传递动态内存
用函数返回值来传递动态内存这种方法虽然好用,但是常常有人把return语句用错了。这里强调不要用return语句返回指向“栈内存”的指针,因为该内存在函数结束时自动消亡,见示例7-4-4。
char *GetString(void)
{
char p[] = "hello world";//用数组
return p; //
编译器将提出警告
}
|
void Test4(void)
{
char *str = NULL;
str = GetString(); // str
的内容是垃圾
cout<< str << endl;
}
|
示例7-4-4 return语句返回指向“栈内存”的指针
用调试器逐步跟踪Test4,发现执行str = GetString语句后str不再是NULL指针,但是str的内容不是“hello world”
而是垃圾。
如果把示例7-4-4改写成示例7-4-5
,会怎么样?
char *GetString2(void)
{
char *p = "hello world";//用指针
return p;
}
|
void Test5(void)
{
char *str = NULL;
str = GetString2();
cout<< str << endl;
}
|
示例7-4-5 return语句返回常量字符串
函数Test5运行虽然不会出错,但是函数GetString2的设计概念却是错误的。因为GetString2内的“hello world”是常量字符串,位于静态存储区,它在程序生命期内恒定不变。无论什么时候调用GetString2,它返回的始终是同一个“只读”的内存块。
程序运行如下:
vc->File->new->c++source file
#include "iostream.h"
#include "stdio.h"
#include "string.h"
#include "malloc.h"
void GetMemory(char *p,int num);
void Test(void);
void GetMemory2(char **p,int num);
void Test2(void);
char *GetMemory3(int num);
void Test3(void);
char *GetString(void);
void Test4(void);
char *GetString2(void);
void Test5(void);
void main()
{
// Test();
Test2();
Test3();
Test4();
Test5();
}
void GetMemory(char *p,int num)//设计错误,却非常隐蔽
{
p=(char*)malloc(sizeof(char)*num);
}
void Test(void)
{
char *str=NULL;
GetMemory(str,100);
strcpy(str,"hello");
cout<<str<<endl;
}
void GetMemory2(char **p,int num)
{
*p=(char*)malloc(sizeof(char)*num);
}
void Test2(void)
{
char *str=NULL;
GetMemory2(&str,100);//注意参数传递
strcpy(str,"hello");
cout<<str<<endl;
free(str);//保持与malloc的配对
}
char *GetMemory3(int num)
{
char *p = (char*)malloc(sizeof(char)*num);
return p;
}
void Test3(void)
{
char *str=NULL;
str=GetMemory3(100);
strcpy(str,"hello");
cout<<str<<endl;
free(str);//保持与malloc的配对
}
char *GetString(void)
{
char p[]="hello";
return p;//warning:return address of local variable or temporary(数组属于局部变量)
}
void Test4(void)
{
char *str=NULL;
str=GetString();
cout<<"以下内容为垃圾: ";
cout<<str<<endl;
}
char *GetString2(void)
{
char *p="hello";
return p;
}
void Test5(void)
{
char *str=NULL;
str=GetString2();
cout<<str<<endl;
}
运行结果:
hello
hello
以下内容为垃圾:(随意的内容)
hello
发表评论
-
COM(Component Object Model)组件介绍
2013-01-15 17:38 1478COM component(COM组件)是微软公司为了计算机 ... -
scanf的用法
2012-05-31 23:37 1425scanf()函数的用法和实 ... -
定义计算变量相对于结构体偏移量的宏
2012-05-30 22:42 2788#include <stdio.h> #incl ... -
C语言一些有用的宏定义
2012-05-30 22:36 1739C语言宏定义技巧(常用宏定义) 写好C语 ... -
C语言const
2012-05-30 14:35 1231原文地址:http://hi.baidu. ... -
C语言void指针
2012-05-29 09:50 13241.概述 本文将对void关键字的深刻含义进行解说,并 ... -
C语言中#line 宏说明
2012-05-28 09:38 1817c语言里有个很少用到的宏 #line,这个宏通常是和__LIN ... -
C语言中宏的一些特别用法
2012-05-28 09:36 1689转载 C语言中如何使用宏C(和C++)中的宏(Macro)属 ... -
C语言编译执行的全过程
2012-05-28 09:13 1198编译,编译程序读取源程序(字符流),对之进行词法和语法的分 ... -
C++新型头文件与名称空间的作用
2012-05-25 09:06 18361.20 新型头文件与名字 ... -
程序在内存中运行的奥秘
2010-07-01 12:18 1814内存管理是操作系统的核心功能,无论对于开发者还是系统管理员内存 ... -
堆和栈的区别
2010-06-29 10:56 1610栈是随函数被调用时分 ... -
原码,补码,反码(针对byte(128) = -128的问题)
2010-06-25 16:40 4070int a = 128; byte b = (byte)a; ... -
链表常见笔试题
2010-06-25 11:22 3414链表的一些常见笔试面试问题总结及代码 ... -
C与C++中struct的区别,以及C++中struct与Class的区别
2010-06-25 10:44 4160C中struct只可以放成员变量,没有访问权限限制,外部可以访 ... -
C++中的inline用法总结
2010-05-26 22:26 18757inline函数的作用 ... -
C++枚举类型用途及定义详解
2010-05-26 21:14 4547C++编程语言作为一种功 ... -
C++ Template 中的typename、class关键字区别
2010-05-19 19:27 3261在c++Template中很多地 ... -
C++与Java比较(转)
2010-04-30 23:02 4424“作为一名C++程序员,我们早已掌握了面向对象程序设计的基本概 ... -
几款常见C++编译器的比较
2010-04-30 22:58 5691另外,就我个人的一点点经验来看,vs 2005中的C++编译器 ...
相关推荐
5. C++中指针和引用的区别 35 6. const char*, char const*, char*const的区别 36 7. C中可变参数函数实现 38 8. C程序内存中组成部分 41 9. C编程拾粹 42 10. C语言中实现数组的动态增长 44 11. C语言中的位...
5. C++中指针和引用的区别 35 6. const char*, char const*, char*const的区别 36 7. C中可变参数函数实现 38 8. C程序内存中组成部分 41 9. C编程拾粹 42 10. C语言中实现数组的动态增长 44 11. C语言中的位运算 46...
5. C++中指针和引用的区别 35 6. const char*, char const*, char*const的区别 36 7. C中可变参数函数实现 38 8. C程序内存中组成部分 41 9. C编程拾粹 42 10. C语言中实现数组的动态增长 44 11. C语言中的位运算 46...
5. C++中指针和引用的区别 35 6. const char*, char const*, char*const的区别 36 7. C中可变参数函数实现 38 8. C程序内存中组成部分 41 9. C编程拾粹 42 10. C语言中实现数组的动态增长 44 11. C语言中的位运算 46...
5. C++中指针和引用的区别 35 6. const char*, char const*, char*const的区别 36 7. C中可变参数函数实现 38 8. C程序内存中组成部分 41 9. C编程拾粹 42 10. C语言中实现数组的动态增长 44 11. C语言中的位运算 46...
5. C++中指针和引用的区别 35 6. const char*, char const*, char*const的区别 36 7. C中可变参数函数实现 38 8. C程序内存中组成部分 41 9. C编程拾粹 42 10. C语言中实现数组的动态增长 44 11. C语言中的位运算 46...
5. C++中指针和引用的区别 35 6. const char*, char const*, char*const的区别 36 7. C中可变参数函数实现 38 8. C程序内存中组成部分 41 9. C编程拾粹 42 10. C语言中实现数组的动态增长 44 11. C语言中的位运算 46...
5. C++中指针和引用的区别 35 6. const char*, char const*, char*const的区别 36 7. C中可变参数函数实现 38 8. C程序内存中组成部分 41 9. C编程拾粹 42 10. C语言中实现数组的动态增长 44 11. C语言中的位...
2、C++中指针和引用的区别 指针有自己的一块空间,而引用只是一个别名; 使用 sizeof 看一个指针的大小为4字节(32位,如果要是64位的话指针为8字节),而引用则是被引用对象的大小; 指针可以被初始化为 NULL,而...
4. c/c++中指针学习的两个绝好例子 ............................................................ 6 5. 入门教程:C++中的const限定修饰符 ....................................................... 8 6. 新手...
C 和 C++,您必须进行内存管理。本文将介绍手工的、半手工的以及自动的内存管理实践的基本概念。 追溯到在 Apple II 上进行汇编语言编程的时代,那时内存管理还不是个大问题。您实际上在运行整个系统。系统有...
在大部分系统语言中,比如 C 和 C++,您必须进行内存管理。本文将介绍手工的、半手工的以及自动的内存管理实践的基本概念。 追溯到在 Apple II 上进行汇编语言编程的时代,那时内存管理还不是个大问题。您实际上在...
C++中指针和引用的区别 ................................................................................................................. 31 6. const char*, char const*, char*const的区别 .................