今天我哥哥的LP大人要我给他写一个小程序,本来用C#写的,但是她机器上没有.NET,于是改用C++。
首次代码如下:
奇妙的事情发生了……
中断还是在strlen.asm中,这让我还以为是strlen有问题,所以就自写了一个strlen,代码如下:
去掉原来的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类型没有初始化,那么比如下面代码
你猜会输出什么,告诉你,其实什么也不会输出,因为string没有初始化,该变量在出了for的循环作用域后又会自动变为未初始化状态。如果你一开始string test=null;那么最后就会输出4。具体大家自己试试吧。这次不再絮述。
首次代码如下:
//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;
}
#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;
}
{
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 test;
for(int i=0;i<4;i++)
test=i.ToString();
Console.Write("{0}",test);
}
你猜会输出什么,告诉你,其实什么也不会输出,因为string没有初始化,该变量在出了for的循环作用域后又会自动变为未初始化状态。如果你一开始string test=null;那么最后就会输出4。具体大家自己试试吧。这次不再絮述。