首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >strcat分段故障

strcat分段故障
EN

Stack Overflow用户
提问于 2010-11-30 08:48:07
回答 7查看 3.5K关注 0票数 1

这里对strcat的第二个调用是生成一个分段错误,为什么?

代码语言:javascript
复制
#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;
}
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2010-11-30 09:29:07

我测试了您的代码,还看到了第二个strcat()上的段错误。我发现在我的系统上,在堆栈上,command[250]是在whitespaceseparator[2]之后立即分配的:

代码语言:javascript
复制
(gdb) p &whitespaceseparator 
$1 = (char (*)[2]) 0xbf90acd4
(gdb) p &command
$2 = (char (*)[250]) 0xbf90acd6

例如(这里command开始"foo..."),事情是这样布局的:

代码语言:javascript
复制
 whitespaceseparator
  |
  |      command
  |       |
  v       v
+---+---+---+---+---+---+---+---+
|' '| 0 |'f'|'o'|'o'|'.'|'.'|'.'| ...
+---+---+---+---+---+---+---+---+

我不能保证在您的系统上也会发生同样的事情(即使在同一编译器的不同版本之间,堆栈上的局部变量的布局也可能不同),但这似乎是可能的。在我的例子中,具体情况如下:

正如其他人所说,strcat()将第二个字符串附加到第一个字符串之后(结果将等于第一个参数)。因此,第一个strcat()溢出whitespaceseparator[] (并将whitespaceseparator作为whitespace_and_pid返回):

代码语言:javascript
复制
+---+---+---+---+---+---+---+---+
|' '|'1'|'2'|'3'|'4'| 0 |'.'|'.'| ...
+---+---+---+---+---+---+---+---+

第二个strcat()尝试将whitespace_and_pid (== whitespaceseparator)附加到command处的字符串。副本的第一个字符将覆盖字符串以command结尾的0

代码语言:javascript
复制
  |    ===copy===>    |
  v                   v
+---+---+---+---+---+---+---+---+
|' '|'1'|'2'|'3'|'4'|' '|'.'|'.'| ...
+---+---+---+---+---+---+---+---+

复制继续进行...

代码语言:javascript
复制
      |    ===copy===>    |
      v                   v
+---+---+---+---+---+---+---+---+
|' '|'1'|'2'|'3'|'4'|' '|'1'|'.'| ...
+---+---+---+---+---+---+---+---+

          |    ===copy===>    |
          v                   v
+---+---+---+---+---+---+---+---+
|' '|'1'|'2'|'3'|'4'|' '|'1'|'2'| ...
+---+---+---+---+---+---+---+---+

并将继续复制" 1234 1234 1234"...直到它从进程地址空间的末尾掉下来,这时您会得到一个段错误。

票数 4
EN

Stack Overflow用户

发布于 2010-11-30 08:50:53

strcat并不是你想的那样。它修改其第一个参数所指向的字符串。在本例中,该字符串包含在一个2字节数组中,因此该数组溢出。

票数 3
EN

Stack Overflow用户

发布于 2010-11-30 08:52:33

为了避免缓冲区溢出错误,但使用strcat时应使用strncat函数。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4309577

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档