c - strcat 段错误

标签 c strcat

此处对 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;
}

最佳答案

我试过你的代码,也看到了第二个 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"...直到它脱离进程地址空间的末尾,此时您会遇到段错误。

关于c - strcat 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4309577/

相关文章:

c - 写的字符比 malloced 多。为什么它不会失败?

c - #在c中定义数组格式

c - makefile编译多个目标

c - 简单的立方和平方和函数不会运行 (C)

连接 C 字符串

C Segmentation Fault,多个警告

c - strcat() 实现有效,但最后导致核心转储

c - 如何添加这个长变量而不破坏下面的 union ?

c - strlen() 的这个基本重新实现如何找到长度?

在C中将字符串转换为数字