70分重分求解!奇怪,用字符串常量就行,用字符串变量就出错,70分重分求解!
首先,我有这样一个函数,用于构造一个字符串str:
char* build_str( char* str_buf, char* a, char* b )
{
//将a,b两个字符串拼接起来构成str
strcpy( str_buf, a );
strcat( str_buf, " " );//这里业务需要一个空格
strcat( str_buf, b );
return str_addr;
}
接下来,我有这样一个函数,是要使用这个str的:
int A( char* str )
{
//函数体省略
}
问题来了:
当我使用字符串常量,如下:
A( "help me " );
就可以得到正确的结果;
而当我调用build_str构造一个str出来时,如下:
char mystr[10];
build_str( mystr, "help ", "me " );
A( mystr );
最后得到的结果就是一堆乱码。
但我去跟踪调试的时候,看到str构造出的结果是对的,只是一使用就错了。
重分求解啊,谢谢大家了!
[解决办法]
这样声明一下看看
char* build_str( char* str_buf,const char* a,const char* b )
[解决办法]
更正:
build_str()函数的返回值是,
return str_buf;
////////////////////////////////
而当我调用build_str构造一个str出来时,如下:
char mystr[10];
//更改char *mystr[]
因为你原来的函数原型是:char* build_str( char* str_buf, char* a, char* b )
这里不建议以上改更方案.
我们可以更改函数:
char build_str( char &, char & , char & )
更正:
char build_str( char &, char & , char & )
char build_str( char &str_buf, const char &a, const char &b )
{
//将a,b两个字符串拼接起来构成str
strcpy( str_buf, a );throw " ";
strcat( str_buf, " " );throw " ";//这里业务需要一个空格
strcat( str_buf, b );throw " ";
return str_buf;
}
int A( char& str )
{
//函数体省略
}
[解决办法]
看不出什么不一样的,只能建议函数原型改成:
char* build_str( char* str_buf, const char* a, const char* b )
主要是要仔细检查A()函数
[解决办法]
你mystr没有清空,用字符串常量时候是在全局初始化的,编译器会自动将这块内存置零。而你用字符串变量,是从栈里面分配内存,编译器不会做初始化的工作,里面会存有这块内存以前的数据。
你自己在定义变量的时候改成:
char mystr[10]={0};
就OK了
[解决办法]
#include <iostream>
#include <cstdlib>
using namespace std;
char* build_str( char* str_buf, char* a, char* b )
{
strcpy( str_buf, a );
strcat( str_buf, " " );
strcat( str_buf, b );
return str_buf;
}
void test( const char *A )
{
cout < < A < < endl;
}
int main( void )
{
char str[10] = {0};
build_str( str, "help ", "me " );
test( str );
return 0;
}
在g++ 下:
help me
没有问题,不知道LZ用什么编译器
[解决办法]
char mystr[10];
build_str( mystr, "help ", "me " );
A( mystr );
char* build_str( char* str_buf, char* a, char* b ) 改为
char* build_str( char** str_buf, char* a, char* b )
{
//将a,b两个字符串拼接起来构成str
strcpy( *str_buf, a );
strcat( *str_buf, " " );//这里业务需要一个空格
strcat( *str_buf, b );
return *str_buf;
}
拿分走人。。。。。
lz试一试 肯定没问题
[解决办法]
tc 2.0下这样没有问题
#include <stdio.h>
#include <conio.h>
char* build_str( char* str_buf, char* a, char* b )
{
strcpy( str_buf, a );
strcat( str_buf, " " );
strcat( str_buf, b );
return str_buf;
}
int A( char* str )
{
printf( "%s\n ",str);
}
int main()
{
char mystr[10];
char* p = build_str(mystr, "help ", "me ");
A(mystr);
/* printf( "%s\n ",mystr);*/
getch();
}
[解决办法]
to : Jodiman(想自看大海)
我作了如下更改,就得到了正确的结果,为什么?
//char mystr[10];
char* mystr;
mystr = new char[10]; //分配堆空间
build_str( mystr, "help ", "me " );
A( mystr );
delete(mystr); //释放堆空间
给mystr分配了堆空间,就得到了正确的结果。
但我还是有些不解,为什么在栈上分配的空间就出错,在堆上就没问题呢?
========================================================
栈上的数组是不会被自动初始化为零值的,而堆上的空间会被初始化零值。所以在栈上的时候,字符串不以 '\0 '结束
[解决办法]
明显A函数的问题。
最起码导致的问题有三种可能。
一, 越界(就是A函数访问函数参数(指针)的时候,超过了10个字节,
但从运行状态来说(乱码),可能不大)
二, stack中的指令被执行。 如果A函数会执行传递过来的buf, 那么在开了dep
(数据执行保护)的机器上, 执行stack的代码,会导致异常,可能不大
三, A函数可能是把这个指针暂时保留起来了(比如保存到类的成员m_str中)但暂时不处理
最后, 调用A函数的函数已经执行完毕了(stack中的内存已经不确定了,
以后会根据后面函数的push操作,定义变量操作等改变), 然后在后续的过程中
再次去访问这个m_str,导致乱码。 这种可能最大
对于new出来的内存,其实是在heap中的。 heap是进程共享,模块操作的单位。 所以不会
受到你函数的掉用退出所影响到。