惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
D
Docker
月光博客
月光博客
MongoDB | Blog
MongoDB | Blog
Vercel News
Vercel News
美团技术团队
博客园 - 叶小钗
I
InfoQ
Jina AI
Jina AI
博客园 - 司徒正美
雷峰网
雷峰网
B
Blog
Y
Y Combinator Blog
A
About on SuperTechFans
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
大猫的无限游戏
大猫的无限游戏
Microsoft Security Blog
Microsoft Security Blog
Stack Overflow Blog
Stack Overflow Blog
腾讯CDC
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Recent Announcements
Recent Announcements
V
V2EX
N
Netflix TechBlog - Medium

博客园 - Samson小天

My researches during my college life. 一些底层的简单东西。 IAT HOOK 实现进程保护 大年初一,总结一下去年的十大事件~ 解决多线程产生的“以前的函数求值超时,函数求值被禁用。必须继续执行才能重新启用函数求值” Guessing Game解题报告 (pku 2328) 分析一道08年10月12日的江苏省程序设计大赛正赛题 数学之美 C# 自定义实体类或集合的自动排序 UltraRun is released 简单的QQ游戏中大家来找茬外挂编写思路 最近写C++程序时关于GetLastError的感悟。 在Vista的UAC下检查程序是否具有Admin权限及应用程序的权限切换 从程序开发角度谈类的封装性。 教你如何解决“线程间操作无效: 从不是创建控件的线程访问它” C#中调用WIN32的API 小记delegate,简单的委托介绍 一个计算简单数学表达式值的算法。 对C#中ADO.NET开发的理解
string类型的初值不是随便赋的,记一次奇怪的访问冲突事件
Samson小天 · 2008-03-06 · via 博客园 - Samson小天

    今天我哥哥的LP大人要我给他写一个小程序,本来用C#写的,但是她机器上没有.NET,于是改用C++。
    首次代码如下:

//Main.cpp


#include 
<iostream>
#include 
<string>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::strlen;

void Translate(char* p_str)
{
    
int Length=strlen(p_str);
    
for (int i=0;i<Length;i++)
    
{
        
switch (*p_str)
        
{
        
case '1':
            
*p_str='N';
            
break;
        
case '2':
            
*p_str='E';
            
break;
        
case '3':
            
*p_str='U';
            
break;
        
case '4':
            
*p_str='M';
            
break;
        
case '5':
            
*p_str='A';
            
break;
        
case '6':
            
*p_str='T';
            
break;
        
case '7':
            
*p_str='I';
            
break;
        
case '8':
            
*p_str='C';
            
break;
        
case '9':
            
*p_str='O';
            
break;
        
case '0':
            
*p_str='S';
            
break;
        }

        p_str
++;
    }

}


int main()
{
    
string Numbers=NULL;
    
while (Numbers!="N"&&Numbers!="n")
    
{
    cout
<<"G6472 Converter  ---Samson Product"<<endl<<endl;
    cout
<<"Please input some numbers:"<<endl;
    cin
>>Numbers;
    cout
<<"The number translated into chars are:"<<endl;
    Translate(
&Numbers[0]);
    cout
<<Numbers<<endl;
    cout
<<"press N to continue convert, any thing else to Continue"<<endl;
    cin
>>Numbers;
    cout
<<endl;
    }

    
return 0;
}

    奇妙的事情发生了……
    
    中断还是在strlen.asm中,这让我还以为是strlen有问题,所以就自写了一个strlen,代码如下:

int MyStrlen(char* p)
{
    
int Length=0;
    
while(*p++)
    
{
        Length
++;
    }

    
return Length;
}

    去掉原来的strlen调用和using声明后问题依旧...= =||
    又奇怪又囧中。于是开了虚拟机XP在VC 6.0用标准C来写,其结果同样悲惨。但是XP下的相同结果让我明白绝对不是strlen的问题,标准C也是用自写的mystrlen函数,并且用.h的方法include头文件。所以我开始向代码中寻找问题。
    当我看到string Numbers=NULL的时候我突然楞了一下。本来我是不想赋初值的,但是我们老师说任何变量定义后最好都初始化,而NULL正好满足了这个变量里既没有东西有初始化了,所以我就用了(注意,没有初始化和初始化为空时有区别的,这个会在文末小题一下)。于是我将此句改为string Numbers="Y",结果程序通过了……囧||。原来初始化为NULL是没有问题的,但是之后和"N"做比较时程序自动访问Numbers[0]位置,结果造成溢出,也就是导致访问冲突的原因。
    小结:其实这个问题用内存调试可以很快调出来,我看见我叔叔用过一次,但是在我机器上什么内存1,内存2...内存4我都不知道选哪个监视,纠结中……||希望此文能给和我遇到一样错误的人一点参考。所以即使你知道这个变量的初始化值绝对不会用到,变量的初始化也不是很随便的。

注:在C#中,如果一个string类型没有初始化,那么比如下面代码

public void test()
{
  
string test;
  
for(int i=0;i<4;i++)
     test
=i.ToString();
  Console.Write(
"{0}",test);
}


    你猜会输出什么,告诉你,其实什么也不会输出,因为string没有初始化,该变量在出了for的循环作用域后又会自动变为未初始化状态。如果你一开始string test=null;那么最后就会输出4。具体大家自己试试吧。这次不再絮述。