malloc()参数为0的情况

  问题来自于《程序员面试宝典(第三版)》第12.2节问题9(这里不评价《程序员面试宝典》,就题论题):

下面的代码片段输出是什么?为什么?

char *ptr;
if((ptr = (char *)malloc(0))==NULL)
puts("Got a null pointer");
else
puts("Got a valid pointer");

 解析:......故意把0值传给了函数malloc,得到了一个合法的指针,这就是上面的代码,该代码的输出是"Got a valid pointer"。

 

  这个“解析”根本就没有解析嘛。好在查资料很方便,《C语言参考手册》上说“如果请求的长度为0,则标准C语言函数返回一个null指针或不能用于访问对象的非null指针。”或者你也可以直接在linux里man malloc来查阅手册:

void *malloc(size_t size);

...

malloc() allocates size bytes and returns a pointer to the allocated memory. The memory is not cleared. If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().

  可见,原题的if是为了鉴别malloc()返回值是NULL,还是一个唯一的待释放指针;而不是“解析”中的必然是非NULL的“合法指针”,因此输出也不是确定的,尽管我用gcc和clang多次编译运行,输出都是"Got a valid pointer"。

  顺便再说说后面的代码,同样出自《程序员面试宝典》:

将程序改成:

char *ptr;
if(int pp = (strlen(ptr=(char *)malloc(0))) == 0)
puts("Got a null pointer");
else
puts("Got a valid pointer");

或者

char *ptr;
if(int pp = (sizeof(ptr=(char *)malloc(0))) == 4)
puts("Got a null pointer");
else
puts("Got a valid pointer");

如果求ptr的strlen的值和sizeof的值,该代码的输出是"Got a null pointer"。

  第一段程序的分析和上面一样,如果不幸返回了一个唯一的待释放非NULL指针,行为不可预测;只不过这个if判断写的有些繁琐:注意到“==”优先级高于"=",而赋值语句的值是其左值。

  此时malloc(0)返回了一个可用于free()释放的唯一指针(非NULL),而且将它传给strlen(),返回值为0,这样看来,它用'\0'进行填充的(即内容是NULL而非指针指向NULL)。但这一点并没有在man中提到,个人猜测是和实现有关的。
  除此以外,顺便考察了strlen((char*)NULL)的行为:会导致段错误。

  第二段程序呢,sizeof()里写了一大堆,其实只是计算了sizeof(char *),在32位机上结果当然是4,而sizeof()里面的malloc()根本没有执行。和前面两段代码不同,关键点不在malloc而是sizeof。

  对于Dic4000提到的问题“实际项目中什么情况下会给malloc传0?既然是开辟内存,传0不是没有意义吗?”的个人理解:

1.一般确实不会直接写malloc(0),但是可能在程序某个地方写int n;int *p = malloc(n);在别的地方又令n=0,造成了参数为0的情况。若是无心而为,可能导致某种bug。如果了解malloc(0)的行为,找bug相对而言会简单点。

2.面试题各种稀奇古怪的问题都有可能出现,有的面试官认为考这些边界条件、特殊参数什么的能考察一个程序员的功底。

 

其他参考文章:

  @净坛使者进行的更深一步的挖掘,文章和回复都很有价值:关于malloc(0)的返回值问题--这两天的总结与实践篇

  @garbageMan 谈面试题:别太把面试题当回事儿

 

更蛋疼的问题:

  如果给malloc()传一个负参数会怎么样?malloc()的参数是size_t类型,一般是无符号数,负值会被转化它对应于size_t中的对应值。经我测试,当这个值大于malloc()所能分配的上限时,返回NULL。

 

复制代码
#include <stdio.h>
#include <stdlib.h>
int main() {
size_t t;
t = (size_t)-1;
printf("%u\n",t);
char * p = malloc(t);
if(p==NULL)
printf("NULL\n");
}
复制代码

 

  (刚刚在stackoverflow上看到的http://stackoverflow.com/questions/17925771/what-happens-when-we-call-malloc-with-negative-paramter)


作者:五岳
出处:http://www.cnblogs.com/wuyuegb2312
对于标题未标注为“转载”的文章均为原创,其版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/353644.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

铁乐学python_Day42_锁和队列

铁乐学python_Day42_锁和队列 例&#xff1a;多个线程抢占资源的情况 from threading import Thread import timedef work():global ntemp ntime.sleep(0.1)n temp - 1if __name__ __main__:n 100l []for i in range(100):p Thread(targetwork)l.append(p)p.start()for p…

hibernate 懒加载_Hibernate懒/急加载示例

hibernate 懒加载这篇文章将重点讨论为什么以及如何在应用程序中使用称为LAZY和EAGER加载的概念&#xff0c;以及如何使用Spring的Hibernate模板以EAGER方式加载LAZY实体。 当然&#xff0c;正如标题本身所暗示的那样&#xff0c;我们将通过一个示例来说明这一点。 场景就是这样…

C++ 关键字typeid

转载网址&#xff1a;http://www.cppblog.com/smagle/archive/2010/05/14/115286.aspx 在揭开typeid神秘面纱之前&#xff0c;我们先来了解一下RTTI&#xff08;Run-Time Type Identification&#xff0c;运行时类型识别&#xff09;&#xff0c;它使程序能够获取由基指针或引用…

使用Apache Camel进行负载平衡

在此示例中&#xff0c;我们将向您展示如何使用Apache Camel作为系统的负载平衡器。 在计算机世界中&#xff0c;负载均衡器是一种充当反向代理并在许多服务器之间分配网络或应用程序流量的设备。 负载平衡器用于增加容量&#xff08;并发用户&#xff09;和应用程序的可靠性。…

Java8-Guava实战示例

示例一&#xff1a; 跟示例三对比一下&#xff0c;尽量用示例三 List<InvoiceQueryBean> invoiceQueryBeanList new ArrayList<>(); List<String> invoices Lists.newArrayList(Iterators.transform(invoiceQueryBeanList.iterator(), new Function<Inv…

java项目构建部署包

博客分类&#xff1a; JAVA Java 工程在生产环境运行时&#xff0c;一般需要构建成一个jar&#xff0c;同时在运行时需要把依赖的jar添加到classpath中去&#xff0c;如果直接运行添加classpath很不方便&#xff0c;比较方便的是创建一个shell脚本。在公司项目中看到把工程代码…

不错的自学网站合集

一、网站类1、假期在家如何查找论文资料&#xff1f;只需登录中国图书馆http://t.cn/hYmDq&#xff08;需注册&#xff09;&#xff0c;即可免费下载各种期刊和学位论文2、全球免费开放的电子图书馆http://t.cn/h4hJUf3、给大家推荐个神网站&#xff0c;只要是外文书籍基本上都…

c++中关于字符串的读入——cin、getline、get、gtes(查询+思考+总结)

1、cin读入一个字符&#xff1a;char c;cin>>c;2、cin读入一个字符串&#xff1a;char s[10];cin >> s;&#xff08;c风格字符串&#xff09; string str;cin >> str;&#xff08;c的string&#xff09;3、cin.get()读入一个字符&#xff1a;char c;ccin.…

java文档注释和标题注释_Java注释:探究和解释

java文档注释和标题注释Java 5 SE的许多出色功能之一是Annotations构造的引入。 注释是一些标签&#xff0c;可以将其插入到程序源代码中&#xff0c;以使用某种工具对其进行处理并使其变得有意义。 注释处理工具通常使用&#xff08;Java 5 SE的&#xff09;Reflection API在J…

shell 脚本初步,启动可执行 jar 文件

可能很多同学在看到这篇文章的时候是第一次接触 shell 脚本。所以我们首先需要了解什么是 shell 脚本。在 Windows 里我们经常会看到一种扩展名为 .bat 的文件&#xff0c;它称为批处理文件。批处理文件的作用是把许多个命令放在一个文件里&#xff0c;当运行这个文件的时候就执…

使用Java创建DynamoDB表

在这篇文章中&#xff0c;我们将使用java方法在DynamoDB数据库上创建表。 在开始之前&#xff0c;我们需要安装本地dynamodb&#xff0c;因为我们要避免使用dynamodb的任何费用。 有一个以前的岗位上本地dynamodb。 如果您使用docker&#xff0c;则可以找到本地dynamodb映像&a…

表达式前后缀表达形式 [zz]

(2012-09-12 13:08:39) 转载▼标签&#xff1a; 杂谈 转自&#xff1a;http://blog.csdn.net/whatforever/article/details/673853835,15,,80,70,-,*,20,/ //后缀表达方式(((3515)*(80-70))/20&#xff09;25 //中缀表达方式 /,*,,35,15,-,80,70, 2…

引用:初探Sql Server 执行计划及Sql查询优化

引用:初探Sql Server 执行计划及Sql查询优化 原文:引用:初探Sql Server 执行计划及Sql查询优化初探Sql Server 执行计划及Sql查询优化 收藏MSSQL优化之————探索MSSQL执行计划作者&#xff1a;no_mIss最近总想整理下对MSSQL的一些理解与感悟&#xff0c;却一直没有心思和时间…

Cities

问题 C: Cities 时间限制: 1 Sec 内存限制: 128 MB提交: 87 解决: 61[提交][状态][讨论版][命题人:admin]题目描述 There are n cities in Byteland, and the ith city has a value ai. The cost of building a bidirectional road between two cities is the sum of their v…

spring观察者模式_Spring事件的观察者模式

spring观察者模式介绍 观察者模式的本质是“定义对象之间的一对多依赖关系&#xff0c;以便当一个对象改变状态时&#xff0c;其所有依赖关系都会被通知并自动更新”。 GoF。 观察者模式是发布/订阅模式的子集&#xff0c;它允许许多观察者对象查看事件。 可以在不同的情况下使…

Lombok,自动值和不可变项

我喜欢布兰登&#xff08;Brandon &#xff09;在博客文章中比较Project Lombok &#xff0c; AutoValue和Immutables的建议 &#xff0c;而这篇文章试图做到这一点。 我已经简要概述了Project Lombok &#xff0c; AutoValue和Immutables &#xff0c;但是这篇文章有所不同&am…

linux对于zombie的处理

(Linux基础)[僵尸进程处理] 今天在服务器上推送项目的时候&#xff0c;突然发现很卡。就用top查看了一下&#xff0c;果然此事不简单啊。 top - 10:39:16 up 20 days, 23:11, 2 users, load average: 1.13, 1.09, 1.03 Tasks: 204 total, 2 running, 196 sleeping, 1 sto…

POJ - 1847 Tram(dijkstra)

题意&#xff1a;有向图有N个点&#xff0c;当电车进入交叉口&#xff08;某点&#xff09;时&#xff0c;它只能在开关指向的方向离开。 如果驾驶员想要采取其他方式&#xff0c;他/她必须手动更换开关。当驾驶员从路口A驶向路口B时&#xff0c;他/她尝试选择将他/她不得不手动…

用interrupt()中断Java线程

Javathread 最近在学习Java线程相关的东西&#xff0c;和大家分享一下&#xff0c;有错误之处欢迎大家指正&#xff0e; 假如我们有一个任务如下&#xff0c;交给一个Java线程来执行&#xff0c;如何才能保证调用interrupt()来中断它呢&#xff1f; Java代码 class ATask imple…

activemq和jms_保证主题,JMS规范和ActiveMQ的消息传递

activemq和jms最近&#xff0c;一位客户要求我仔细研究ActiveMQ的“持久”消息的实现&#xff0c;它如何应用于主题以及在存在非持久订户的故障转移方案中会发生什么。 我已经了解到&#xff0c;JMS语义规定&#xff0c;即使面对消息代理提供程序故障&#xff0c;也只能保证主题…