strcat的分段错误 [英] strcat segmentation fault

查看:137
本文介绍了strcat的分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

第二次调用 strcat的这里生成分段错误,为什么呢?

 的#include<&unistd.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&; SYS / types.h中>
#包括LT&; SYS / stat.h>
#包括LT&;&fcntl.h GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&pthreads.h中GT;INT主(INT ARGC,CHAR *的argv [])
{
         字符命令[250];         //如果(scanf函数(%199s命令)== 1)            得到(命令);
            看跌期权(命令);         INT pipeIntId;         炭whitespaceseparator [2] =;         烧焦pidstring [30];         INT PID = GETPID();         sprintf的(pidstring,%D,PID);         字符* whitespace_and_pid;         whitespace_and_pid = strcat的(whitespaceseparator,pidstring);
         字符* command_and_pid;         command_and_pid = strcat的(指挥,whitespace_and_pid); //这里有一个问题,我猜
          如果((mkfifo子(管/ * * pipeName /,0666))== - 1)
          {
              PERROR(错误创建管1);
          出口(1);
          }         如果((pipeIntId =打开(管,/ * * pipeName / O_WRONLY))== - 1)
         {
          PERROR(错误创建管道2);
          出口(1);
         }
         诠释写的;         写=写(pipeIntId,command_and_pid,250); //发送命令+的PID
         关闭(pipeIntId);    返回0;
}


解决方案

我想你的code,也看到了第二个的strcat的段错误()。我发现,命令[250] 终止后,立即分配whitespaceseparator [2] 堆栈我的系统上:

 (GDB)P和; whitespaceseparator
$ 1 =(炭(*)[2])0xbf90acd4
(GDB)P和;命令
$ 2 =(CHAR(*)[250])0xbf90acd6

例如。 (这里命令开始富...),东西都奠定了这样的:

  whitespaceseparator
  |
  |命令
  | |
  v v
+ --- + --- + --- + --- + --- + --- + --- + --- +
| | 0 |'F'|'O'|'O'|'。'|'。'|'。| ...
+ --- + --- + --- + --- + --- + --- + --- + --- +

我不能保证同样的情况,您的系统(当地人布局堆栈甚至不同的版本相同的编译器之间变化),但它似乎有可能。在矿山,这里正是发生什么:

正如其他人所说,的strcat()追加第二个字符串的第一个(结果将等于第一个参数)。所以,第一个的strcat()溢出 whitespaceseparator [] (返回 whitespaceseparator whitespace_and_pid

  + --- + --- + --- + --- + --- + --- + --- + --- +
| '|'1'|'2'|'3'|'4'| 0 |'。'|'。| ...
+ --- + --- + --- + --- + --- + --- + --- + --- +

第二个的strcat()尝试添加 whitespace_and_pid (== whitespaceseparator )的字符串在命令。副本的第一个字符将在命令覆盖该字符串的终止0

  | ===副本===> |
  v v
+ --- + --- + --- + --- + --- + --- + --- + --- +
| '|'1'|'2'|'3'|'4'|' '|'。'|'。| ...
+ --- + --- + --- + --- + --- + --- + --- + --- +

拷贝继续...

  | ===副本===> |
      v v
+ --- + --- + --- + --- + --- + --- + --- + --- +
| '|'1'|'2'|'3'|'4'|' '|'1'|'。| ...
+ --- + --- + --- + --- + --- + --- + --- + --- +          | ===副本===> |
          v v
+ --- + --- + --- + --- + --- + --- + --- + --- +
| '|'1'|'2'|'3'|'4'|' '|'1'|'2'| ...
+ --- + --- + --- + --- + --- + --- + --- + --- +

和将继续复制1234 1234 1234 ...,直到它脱落进程地址空间的结束,此时您会获得一个段错误。

The second call to strcat here is generating a segmentation fault, why?

#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;
}

解决方案

I tried your code, and also see the segfault on the second strcat(). I found that command[250] is allocated immediately after whitespaceseparator[2] on the stack on my system:

(gdb) p &whitespaceseparator 
$1 = (char (*)[2]) 0xbf90acd4
(gdb) p &command
$2 = (char (*)[250]) 0xbf90acd6

e.g. (here command begins "foo..."), things are layed out like this:

 whitespaceseparator
  |
  |      command
  |       |
  v       v
+---+---+---+---+---+---+---+---+
|' '| 0 |'f'|'o'|'o'|'.'|'.'|'.'| ...
+---+---+---+---+---+---+---+---+

I can't guarantee that the same happens on your system (layout of locals on the stack may vary even between different versions of the same compiler), but it seems likely. On mine, here is exactly what happens:

As others have said, strcat() appends the second string to the first (and the result will be equal to the first argument). So, the first strcat() overflows whitespaceseparator[] (and returns whitespaceseparator as whitespace_and_pid):

+---+---+---+---+---+---+---+---+
|' '|'1'|'2'|'3'|'4'| 0 |'.'|'.'| ...
+---+---+---+---+---+---+---+---+

The second strcat() tries to append whitespace_and_pid (== whitespaceseparator) to the string at command. The first character of the copy will overwrite the terminating 0 of the string at command:

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

The copy continues...

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

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

and will carry on copying " 1234 1234 1234"... until it falls off the end of the process address space, at which point you get a segfault.

这篇关于strcat的分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆