为什么这个代码在Linux上工作,而不是在SunOS上工作?

为什么这个代码在Linux上工作,而不是在SunOS上工作?,第1张

概述为什么这个代码在Linux上工作,而不是在SunOS上工作?

#include <stdio.h> int main() { char *str = "11111111-22222222 r-xp 00000000 00:0e 1843624 /lib/libdl.so.0"; unsigned long long start_addr,stop_addr,offset; char* access = NulL; char* filename = NulL; sscanf(str,"%llx-%llx %m[-rwxp] %llx %*[:0-9a-f] %*d %ms",&start_addr,&stop_addr,&access,&offset,&filename); printf("n start : %x,stop : %x,offset : %xn",start_addr,offset); printf("n Permission : %sn",access); printf("n filename : %sn",filename); return 0; }

在linux上,这提供了正确的输出,但在Solaris上该文件被称为libdl.so(在Solaris上没有libdl.so.0),所以我想知道是什么使这种差异,Solaris上没有这个文件,如果我更改为Solaris安装(libdl.so)的文件名,那么它会生成一个分段错误。

$ cc Cperm.c ;./a.out Cperm.c: I funktion "main": Cperm.c:11:3: varning: format "%x" förväntar sig argument av typen "unsigned int",men argument 2 har typen "long long unsigned int" [-Wformat] Cperm.c:11:3: varning: format "%x" förväntar sig argument av typen "unsigned int",men argument 3 har typen "long long unsigned int" [-Wformat] Cperm.c:11:3: varning: format "%x" förväntar sig argument av typen "unsigned int",men argument 4 har typen "long long unsigned int" [-Wformat] start : 11111111,stop : 22222222,offset : 0 Permission : r-xp filename : /lib/libdl.so.0

以上是在Ubuntu上,这里是在Solaris编译没有警告,但产生了分段错误:

uname -a SunOS 5.10 Generic_148888-03 sun4u sparc SUNW,ultra-4 my:~>cc Cperm.c;./a.out start : 0,stop : 11111111,offset : 0 Segmentation fault

更新

my:~>uname -a;gcc -Wall Cperm.c SunOS 5.10 Generic_148888-03 sun4u sparc SUNW,ultra-4 Cperm.c: In function `main': Cperm.c:9: warning: unkNown conversion type character `m' in format Cperm.c:9: warning: long long unsigned int format,pointer arg (arg 5) Cperm.c:9: warning: unkNown conversion type character `m' in format Cperm.c:9: warning: too many arguments for format Cperm.c:11: warning: unsigned int format,different type arg (arg 2) Cperm.c:11: warning: unsigned int format,different type arg (arg 3) Cperm.c:11: warning: unsigned int format,different type arg (arg 4) my:~>gcc Cperm.c my:~>

检查Solaris 10 sscanf的手册页。 这里不支持%m修饰符。

你也应该检查sscanf的返回值。

你的编译器(在Ubuntu上,可能是Solaris,如果你启用了这个警告)告诉你什么是错的:

Cperm.c:11:3: varning: format "%x" förväntar sig argument av typen "unsigned int",men argument 2 har typen "long long unsigned int" [-Wformat] ⋮

你需要在你的printf使用%llx ,就像你在sscanf 。

传递错误类型的参数是未定义的行为。 在linux上,它碰巧工作(这次); 在Solaris上,它没有。

[你真的在问C语言和库的问题,你可能有更好的运气搜索堆栈溢出的答案,而不是在这里。]

编辑:另见msw的答案 ,指出另外一个问题,至少和这个一样重要。

它实际上比它看起来更简单。 您的代码从未分配空间来存储字符串结果。 这个较短的代码有相同的缺陷:

#include <stdio.h> int main() { char *word = NulL; sscanf("hello world","%s",&word); printf("%sn",*word); return 0; }

它可能在一个编译器上“工作”而不在另一个编译器上的原因可能与存储分配的方式有关。 这是由该代码生成的错误:

cperm.c:5:5: error: format '%s' expects argument of type 'char *',but argument 3 has type 'char **'

这似乎并不可怕,但实际上却是致命的。 使用-Werror选项运行gcc会使该警告停止编译,而不是创建a.out 。 正确定义和使用word

char word[64]; sscanf("hello world","%63s",word); printf("%sn",word);

编译没有错误,工作。

总结

以上是内存溢出为你收集整理的为什么这个代码在Linux上工作,而不是在SunOS上工作?全部内容,希望文章能够帮你解决为什么这个代码在Linux上工作,而不是在SunOS上工作?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1221603.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存