| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1048 人关注过本帖
标题:C语言探究 第一课 字符串数组篇
只看楼主 加入收藏
ditg
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:16
帖 子:852
专家分:1937
注 册:2014-4-10
收藏
得分:0 
自问自答,证明自己不是拿来主义,呵呵……通过定义额外的变量并观察其地址特征及生长方向,str[]定义在栈上,*str既不在栈也不在堆上,而在全局/静态区上。基于此,有关是否溢出的问题也就有了分析的基础。

目前关于快慢的问题暂时没想到可靠的实验解释方法。

梦想拥有一台龙芯3A-4000
2014-06-09 14:35
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
每条汇编甚至机器指令的执行效率都不一样,别以为指令少速度就快。但就楼主这个问题看,第二种做法所需要的操作确实比较少,理论上的确会快一点。不过正如我前面说,写程序光看细微的效率是没用的。

授人以渔,不授人以鱼。
2014-06-09 21:04
ditg
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:16
帖 子:852
专家分:1937
注 册:2014-4-10
收藏
得分:0 
“……别以为指令少速度就快……理论上的确会快一点。”这正是我想跟楼主探讨的问题,略同略同。目前我采用了三种方法,实际的差别几乎检测不出来,在多种可能的因素影响下,甚至优劣也是不可预测的,呵呵

梦想拥有一台龙芯3A-4000
2014-06-09 21:26
问遍天下事
Rank: 1
等 级:新手上路
帖 子:15
专家分:3
注 册:2014-6-9
收藏
得分:0 
哇,看得我眼都花了......
2014-06-09 21:34
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
关于第一个代码,看看编译器编译出来的汇编和机器码如何。

源代码:
程序代码:
int main(void)
{
    char str[] = "User32";

    return 0;
}


编译结果:
程序代码:
; Listing generated by Microsoft (R) Optimizing Compiler Version 18.00.30501.0 

    TITLE    D:\項目\測試\VS\test\test1\test1.cpp
    .686P
    .XMM
    include listing.inc
    .model    flat

INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES

PUBLIC    _main
PUBLIC    ??_C@_06MFHBAGGM@User32?$AA@            ; `string'
EXTRN    @_RTC_CheckStackVars@8:PROC
EXTRN    __RTC_InitBase:PROC
EXTRN    __RTC_Shutdown:PROC
;    COMDAT rtc$TMZ
rtc$TMZ    SEGMENT
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ    ENDS
;    COMDAT rtc$IMZ
rtc$IMZ    SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
rtc$IMZ    ENDS
;    COMDAT ??_C@_06MFHBAGGM@User32?$AA@
CONST    SEGMENT
??_C@_06MFHBAGGM@User32?$AA@ DB 'User32', 00H        ; `string'
CONST    ENDS
; Function compile flags: /Odtp /RTCsu /ZI
; File d:\項目\測試\vs\test\test1\test1.cpp
;    COMDAT _main
_TEXT    SEGMENT
_str$ = -12                        ; size = 7
_main    PROC                        ; COMDAT

; 2    : {

  00000    55         push     ebp
  00001    8b ec         mov     ebp, esp
  00003    81 ec d0 00 00
    00         sub     esp, 208        ; 000000d0H
  00009    53         push     ebx
  0000a    56         push     esi
  0000b    57         push     edi
  0000c    8d bd 30 ff ff
    ff         lea     edi, DWORD PTR [ebp-208]
  00012    b9 34 00 00 00     mov     ecx, 52            ; 00000034H
  00017    b8 cc cc cc cc     mov     eax, -858993460        ; ccccccccH
  0001c    f3 ab         rep stosd

; 3    :     char str[] = "User32";

  0001e    a1 00 00 00 00     mov     eax, DWORD PTR ??_C@_06MFHBAGGM@User32?$AA@
  00023    89 45 f4     mov     DWORD PTR _str$[ebp], eax
  00026    66 8b 0d 04 00
    00 00         mov     cx, WORD PTR ??_C@_06MFHBAGGM@User32?$AA@+4
  0002d    66 89 4d f8     mov     WORD PTR _str$[ebp+4], cx
  00031    8a 15 06 00 00
    00         mov     dl, BYTE PTR ??_C@_06MFHBAGGM@User32?$AA@+6
  00037    88 55 fa     mov     BYTE PTR _str$[ebp+6], dl

; 4    :
; 5    :     return 0;

  0003a    33 c0         xor     eax, eax

; 6    : }

  0003c    52         push     edx
  0003d    8b cd         mov     ecx, ebp
  0003f    50         push     eax
  00040    8d 15 00 00 00
    00         lea     edx, DWORD PTR $LN5@main
  00046    e8 00 00 00 00     call     @_RTC_CheckStackVars@8
  0004b    58         pop     eax
  0004c    5a         pop     edx
  0004d    5f         pop     edi
  0004e    5e         pop     esi
  0004f    5b         pop     ebx
  00050    8b e5         mov     esp, ebp
  00052    5d         pop     ebp
  00053    c3         ret     0
$LN5@main:
  00054    01 00 00 00     DD     1
  00058    00 00 00 00     DD     $LN4@main
$LN4@main:
  0005c    f4 ff ff ff     DD     -12            ; fffffff4H
  00060    07 00 00 00     DD     7
  00064    00 00 00 00     DD     $LN3@main
$LN3@main:
  00068    73         DB     115            ; 00000073H
  00069    74         DB     116            ; 00000074H
  0006a    72         DB     114            ; 00000072H
  0006b    00         DB     0
_main    ENDP
_TEXT    ENDS
END


授人以渔,不授人以鱼。
2014-06-11 19:41
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
1楼的反汇编,没有看到常量数据"User32"的长度已被编译时计算出来了(在15楼的汇编码中可以看到),所以其实是不会溢出的。

授人以渔,不授人以鱼。
2014-06-11 19:51
ditg
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:16
帖 子:852
专家分:1937
注 册:2014-4-10
收藏
得分:0 
前面与版主分析一致,缓冲区长度出来了,再scanf检测一下,当字符数超过5时上溢了,呵呵

梦想拥有一台龙芯3A-4000
2014-06-11 21:28
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
str是数组,在运行时使用当然会溢出,但不是初始化时会溢出。第二种指向静态常量区的指针,连修改数据都不可能,不会有攻击性,顶多越界读数据出错。

授人以渔,不授人以鱼。
2014-06-11 21:49
ditg
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:16
帖 子:852
专家分:1937
注 册:2014-4-10
收藏
得分:0 
有道理,初始化,我忽略了,可能这题本身就有问题,呵呵

梦想拥有一台龙芯3A-4000
2014-06-11 21:53
快速回复:C语言探究 第一课 字符串数组篇
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.014566 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved