这里对strcat的第二个调用是生成一个分段错误,为什么?
#include <unistd.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
int main (int argc, char * argv[])
{
char command[250];
//if(scanf("%199s", command) == 1)
gets(command);
puts(command);
int pipeIntId;
char whitespaceseparator[2]=" ";
char pidstring [30];
int pid= getpid();
sprintf(pidstring,"%d", pid);
char * whitespace_and_pid;
whitespace_and_pid = strcat(whitespaceseparator,pidstring);
char * command_and_pid;
command_and_pid=strcat(command,whitespace_and_pid); // here's the problem, I guess
if((mkfifo("pipe"/*pipeName*/,0666))==-1)
{
perror("error creating pipe 1");
exit(1);
}
if((pipeIntId=open("pipe",/*pipeName*/O_WRONLY))==-1)
{
perror("error creating pipe 2");
exit(1);
}
int written;
written=write(pipeIntId,command_and_pid,250); // send the command + the pid
close(pipeIntId);
return 0;
}发布于 2010-11-30 09:29:07
我测试了您的代码,还看到了第二个strcat()上的段错误。我发现在我的系统上,在堆栈上,command[250]是在whitespaceseparator[2]之后立即分配的:
(gdb) p &whitespaceseparator
$1 = (char (*)[2]) 0xbf90acd4
(gdb) p &command
$2 = (char (*)[250]) 0xbf90acd6例如(这里command开始"foo..."),事情是这样布局的:
whitespaceseparator
|
| command
| |
v v
+---+---+---+---+---+---+---+---+
|' '| 0 |'f'|'o'|'o'|'.'|'.'|'.'| ...
+---+---+---+---+---+---+---+---+我不能保证在您的系统上也会发生同样的事情(即使在同一编译器的不同版本之间,堆栈上的局部变量的布局也可能不同),但这似乎是可能的。在我的例子中,具体情况如下:
正如其他人所说,strcat()将第二个字符串附加到第一个字符串之后(结果将等于第一个参数)。因此,第一个strcat()溢出whitespaceseparator[] (并将whitespaceseparator作为whitespace_and_pid返回):
+---+---+---+---+---+---+---+---+
|' '|'1'|'2'|'3'|'4'| 0 |'.'|'.'| ...
+---+---+---+---+---+---+---+---+第二个strcat()尝试将whitespace_and_pid (== whitespaceseparator)附加到command处的字符串。副本的第一个字符将覆盖字符串以command结尾的0
| ===copy===> |
v v
+---+---+---+---+---+---+---+---+
|' '|'1'|'2'|'3'|'4'|' '|'.'|'.'| ...
+---+---+---+---+---+---+---+---+复制继续进行...
| ===copy===> |
v v
+---+---+---+---+---+---+---+---+
|' '|'1'|'2'|'3'|'4'|' '|'1'|'.'| ...
+---+---+---+---+---+---+---+---+
| ===copy===> |
v v
+---+---+---+---+---+---+---+---+
|' '|'1'|'2'|'3'|'4'|' '|'1'|'2'| ...
+---+---+---+---+---+---+---+---+并将继续复制" 1234 1234 1234"...直到它从进程地址空间的末尾掉下来,这时您会得到一个段错误。
发布于 2010-11-30 08:50:53
strcat并不是你想的那样。它修改其第一个参数所指向的字符串。在本例中,该字符串包含在一个2字节数组中,因此该数组溢出。
发布于 2010-11-30 08:52:33
为了避免缓冲区溢出错误,但使用strcat时应使用strncat函数。
https://stackoverflow.com/questions/4309577
复制相似问题