免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: cdphp
打印 上一主题 下一主题

今天遇到的一个极品指针问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2007-12-28 13:37 |只看该作者
这个问题太不极品了

论坛徽章:
0
12 [报告]
发表于 2007-12-28 15:15 |只看该作者
這玩意兒也極品嗎?

论坛徽章:
0
13 [报告]
发表于 2007-12-28 15:22 |只看该作者
想喷人

论坛徽章:
0
14 [报告]
发表于 2007-12-29 20:52 |只看该作者
>> 这个代码之所以崩溃不是因为不符合C99的语义,是因为linker和loader让它崩溃。

不是这样的。

在程序运行之前,作为静态对象的 "something" 字符串字面量和程序代码已经被 load 进来了。Access violation 是因为发生了向只读内存进行写操作,是程序运行时发生的。

论坛徽章:
0
15 [报告]
发表于 2007-12-29 21:03 |只看该作者
原帖由 fallshuang 于 2007-12-27 23:34 发表


不要误导别人,虽然这个代码执行会崩溃,但是编译是绝对可以通过的。 你要搞清楚什么是compiler , 什么是linker and loader 。这个代码之所以崩溃不是因为不符合C99的语义,是因为linker和loader让它崩溃。 ...


我是说LZ 先是定义“string“

     char* string = "something";
然后打印 ”test“
     printf("The result is: %s\n",test);

test 根本就没定义,怎么可能编译过。当然,这应该是LZ的笔误,真正的问题楼上已经指出了。

另外,我对compiler, linker, loader 的基本概念和作用还是明白的,倒是你需要搞清楚什么是编译期,什么是运行时。

[ 本帖最后由 lgfang 于 2007-12-29 22:37 编辑 ]

论坛徽章:
1
申猴
日期:2014-02-11 14:50:31
16 [报告]
发表于 2007-12-30 01:25 |只看该作者
其实这是跟编译器有关的

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
17 [报告]
发表于 2007-12-30 01:39 |只看该作者
鄙视 7 楼,同情 15 楼。

论坛徽章:
0
18 [报告]
发表于 2007-12-30 02:30 |只看该作者
原帖由 whyglinux 于 2007-12-29 20:52 发表
>> 这个代码之所以崩溃不是因为不符合C99的语义,是因为linker和loader让它崩溃。

不是这样的。

在程序运行之前,作为静态对象的 "something" 字符串字面量和程序代码已经被 load 进来了。Access violati ...



我哪句话说错了? 你讲清楚点,不要顾左右而言他。

我的意思再明确重说一遍:
static void foo(void)
{
    char *str = "aaaaaaa";

    printf("%s\n", str);   
    *str = 'b';
    printf("%s\n", str );
}

任何一个支持C99的编译器无论是编译还是链接这段代码,都不应该报error!!!!!


在程序运行之前,作为静态对象的 "something" 字符串字面量和程序代码已经被 load 进来了。

程序运行之前,只是存在于硬盘上的一个elf文件而已。你说load,是什么把字符串常量给load了? load到哪里了 ? 编译链接过程只有relocation, 知道relocation和load的区别么?

"somthing" 这个玩意儿只是被编译器放在elf的rodata段而已,在程序执行前我不知道你说的load操作是谁做的。我倒想听你说清楚。

而且,在执行类似这个函数的代码时,程序完全可以不崩溃!!!!!!! 是否崩溃完全取决于loader

你随便找个2.6 kernel的linux机器,insmod下面这个module, 你看看程序可会崩溃或者出错!!!!  知道内核为什么不报错么? 你能解释么?

#include <linux/module.h>

static void foo(void)
{
    char *str = "aaaaaaa";

    printk("%s\n", str);
    *str = 'b';
    printk("%s\n", str );
}


static int
test_init (void)
{
    printk("Enter test module\n");
    foo();
    return 0;
}

static void
test_exit (void)
{
    printk ("Goodbye, test\n");
}

module_init (test_init);
module_exit (test_exit);

MODULE_LICENSE ("Dual BSD/GPL");


这样修改字符串常量的地方,在内核里我见过不止一处了。知道如何编译内核,使这个模块insmod会出错么? 你可以好好研究下,一个小问题,细挖下去,内涵很多的。

[ 本帖最后由 fallshuang 于 2007-12-30 02:46 编辑 ]

论坛徽章:
0
19 [报告]
发表于 2007-12-30 02:45 |只看该作者
原帖由 flw 于 2007-12-30 01:39 发表
鄙视 7 楼,同情 15 楼。


年轻人啊,  too young , too simple ,  too naive

论坛徽章:
0
20 [报告]
发表于 2008-01-02 10:38 |只看该作者
原帖由 fallshuang 于 2007-12-30 02:30 发表



我哪句话说错了? 你讲清楚点,不要顾左右而言他。

我的意思再明确重说一遍:
static void foo(void)
{
    char *str = "aaaaaaa";

    printf("%s\n", str);   
    *str = 'b';
    print ...

你写的程序试过没?

Snap1.jpg (19.01 KB, 下载次数: 28)

Snap1.jpg
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP