首页 > 编程语言 > 详细

由Linux中管道的buffer,浅谈C语言中char类型字符串拷贝使用strcpy()和=赋值符号的区别

时间:2019-10-20 23:39:30      阅读:98      评论:0      收藏:0      [点我收藏+]

今天在写父子进程用两个单向管道通信时,出现了错误:

Segmentation fault (core dumped)

打开core文件发现:

技术分享图片

 

附上源码:

 1 #include <stdlib.h>
 2 #include <unistd.h>
 3 #include <stdio.h>
 4 #include <sys/wait.h>
 5 #include <errno.h>
 6 #include <string.h>
 7 
 8 void erreur(const char *msg)
 9 {
10     perror(msg);
11 }
12 
13 #define NBCAR 256
14 
15 int main(void)
16 {
17     pid_t pid;
18     int tube[2];
19     int tube2[2];
20     int ret_out, ret_in;
21     char *buffer,*buffer2;
22 
23     if (pipe(tube) == -1) {//from parent to son
24     erreur("Erreur de creation du pipe");
25     exit(EXIT_FAILURE);
26     }
27 if (pipe(tube2) == -1) {//from son to parent
28     erreur("Erreur de creation du pipe");
29     exit(EXIT_FAILURE);
30     }
31     buffer = (char *) malloc(NBCAR * sizeof(char));
32     buffer2 =  (char *) malloc(NBCAR * sizeof(char));
33     switch (pid = fork()) {
34          case (pid_t) -1:
35             erreur("fork");
36         case (pid_t) 0:    
37             close(tube[1]);
38             close(tube2[0]);
39             if (printf("Je suis le fils de PID %d\n write dans le tube : %s\n Nbr Caracteres lus: %d\n",getpid(), buffer, ret_in =write(tube2[1], buffer="tube1 s to p", NBCAR - 1)) == -1) {
40             erreur(" Pb Lecture ");
41             exit(EXIT_FAILURE);
42                 }
43             if (printf("Je suis le fils de PID %d\n Lecture dans le tube : %s\n Nbr Caracteres lus: %d\n",getpid(), buffer2, ret_in =read(tube[0], buffer2, NBCAR - 1)) == -1) {
44             erreur(" Pb Lecture ");
45             exit(EXIT_FAILURE);
46                 }
47 
48             exit(0);
49             break;
50           default:    
51         close(tube[0]);
52         close(tube2[1]);
53         if (printf("Je suis le parent de PID %d\n Lecture dans le tube : %s\n Nbr Caracteres lus: %d\n",getpid(), buffer, ret_in =read(tube2[0], buffer, NBCAR - 1)) == -1) {
54             erreur(" Pb Lecture ");
55             exit(EXIT_FAILURE);}
56         if (printf("Je suis le parent de PID %d\n write dans le tube : %s\n Nbr Caracteres lus: %d\n",getpid(), buffer2, ret_in =write(tube[1], buffer2="tube2 p to s", NBCAR - 1)) == -1) {
57             erreur(" Pb Lecture ");
58             exit(EXIT_FAILURE);}
59 
60     wait(NULL);
61     break;
62 
63     }
64     free(buffer);
65     free(buffer2);
66     return EXIT_SUCCESS;
67 }

 

关于SIGSEGV错误

SIGSEGV --- Segment Fault. The possible cases of your encountering this error are:

1.buffer overflow --- usually caused by a pointer reference out of range.

2.stack overflow --- please keep in mind that the default stack size is 8192K.

3.illegal file access --- file operations are forbidden on our judge system.

后来通过邮件问老师,发现是buffer出现内存泄漏。

先梳理一下C语言中char和字符型、字符串型、单引号、双引号、字符串截止符号的概念:

  首先C中没有专门的字符串变量(没有C++中的String类),单个的char就代表一个字符,赋值时应该是:char c = ‘a‘; 故而单引号表示单个字符。如果用char表示字符串,需要定义char的数组,并有两种主要赋值方法:

char greeting[6] = {H, e, l, l, o, \0};
char greeting[] = "Hello";
//第二例子
char c[10]={I,  , a, m,  , h, a, p, p, y}; 
char c[]="I am happy";

第一种方法:若初值个数小于数组长度,则只将这些字符赋绐数组中前面的元素,其余元素自动定为空字符(即‘\0‘)。

第二种方法:编译器会在初始化数组时,自动把 ‘\0‘ 放在字符串的末尾。

回过头看代码中对buffer的操作:

对buffer和buffer2都分配了256个字节的空间(注意他们是指针,指向256个字节连续空间的首地址),但在赋值时直接对buffer使用等号=,把常量字符串赋给一个指针本身,这显然是不对的····原来分配的两块256字节的内存现在没有指针指向了,最后free的时候并不能把他们释放掉,因此造成内存泄漏

但write()和read()中间参数又必须是指针,这时就需要strcpy()函数,改成:

buffer=strcpy(buffer,"tube1 s to p")
buffer2=strcpy(buffer2,"tube2 p to s")

完美运行,不会报错

 借此机会再复习一下char字符串用等号=赋值和用strcpy()赋值的区别:

等号赋值,两个char指向同一个空间

函数赋值,两个char各有一个相同的字符串拷贝

本文完

参考:

https://blog.csdn.net/yal179/article/details/13019817

https://www.runoob.com/cprogramming/c-strings.html

http://www.voidcn.com/article/p-wlesexyc-ben.html

https://zhidao.baidu.com/question/53110127.html

https://www.runoob.com/cprogramming/c-function-strcpy.html

SIGSEGV错误

https://blog.csdn.net/brace/article/details/1102422

关于core dumped

https://blog.51cto.com/xjsunjie/1954870

https://blog.csdn.net/peiyao456/article/details/70045195

由Linux中管道的buffer,浅谈C语言中char类型字符串拷贝使用strcpy()和=赋值符号的区别

原文:https://www.cnblogs.com/mrlonely2018/p/11710905.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!