假设我调用一个函数void foo (char* fileName);
通过以下调用使用的strcat()作为参数传递给函数
foo("file.txt");
它是确定调用foo()
有:
foo(strcat("file.txt",".binary"));
会造成任何记忆问题?据我了解,我可以面对的唯一问题是堆栈溢出,对吧?
假设我调用一个函数void foo (char* fileName);
通过以下调用使用的strcat()作为参数传递给函数
foo("file.txt");
它是确定调用foo()
有:
foo(strcat("file.txt",".binary"));
会造成任何记忆问题?据我了解,我可以面对的唯一问题是堆栈溢出,对吧?
它会导致任何内存问题?
是的,这是未定义的行为,所以可能会导致崩溃。
据我所知,我唯一可以面对的问题是堆栈溢出,对吧?
不,这里的问题是,strcat
将试图超过字符串文字的末尾写入。
你可以修改你的程序如下:
// Copy into writable memory, and give enough space to fit ".binary"
char fileTxt[16] = "file.txt";
foo(strcat(fileTxt,".binary"));
另外,与字符串文字编译器会为你做串联,如果你简单地把它们一前一后:
foo("file.txt" ".binary");
您提到的方法是否可以在任何C编译器中使用? – Quaker
@Quicker是的,这是标准的一部分,第6.4.5.7节。 – dasblinkenlight
的问题是,对于strcat
,第一个参数将被用于存储结果,所以它必须足够大,以包含串联的结果字符串。
在你的例子中,第一个参数是一个字符串,它不能被修改,并不是说有足够的空间。
它将碰撞; OSX下,我得到:
$ ./a.out
Abort trap: 6
以下堆栈跟踪:
0 libsystem_kernel.dylib 0x00007fff8ad85866 __pthread_kill + 10
1 libsystem_pthread.dylib 0x00007fff83cb136c pthread_kill + 92
2 libsystem_c.dylib 0x00007fff8455dbba abort + 125
3 libsystem_c.dylib 0x00007fff8455dd31 abort_report_np + 181
4 libsystem_c.dylib 0x00007fff845818c5 __chk_fail + 48
5 libsystem_c.dylib 0x00007fff845818d5 __chk_fail_overlap + 16
6 libsystem_c.dylib 0x00007fff845818f7 __chk_overlap + 34
7 libsystem_c.dylib 0x00007fff84581c29 __strcat_chk + 81
8 a.out 0x0000000105c63f09 main + 57
9 libdyld.dylib 0x00007fff8f2255fd start + 1
您正试图在一个字符串常量,它常常会设在只读存储器复制。
第二个字符串的起始字节覆盖第一个字符的空字节。所以第一个字符串(除了不是上面提到的字符串字面量之外)应该足够大以容纳两个字符串的所有字符加上字符串字符的结尾。而且,这些字符串不应该重叠。
你不是真的把两个字符串拼接在一起,对吗?你的实际代码是什么? –
@TimCooper,没有实际的代码,我只是想知道如果我使用'的strcat()',而使用'fopen()函数'例如,将导致堆栈错误。 – Quaker