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


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

    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
     write dans le tube : %s
     Nbr Caracteres lus: %d
    ",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
     Lecture dans le tube : %s
     Nbr Caracteres lus: %d
    ",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
     Lecture dans le tube : %s
     Nbr Caracteres lus: %d
    ",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
     write dans le tube : %s
     Nbr Caracteres lus: %d
    ",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', ''};
    char greeting[] = "Hello";
    //第二例子
    char c[10]={'I', ' ', 'a', 'm', ' ', 'h', 'a', 'p', 'p', 'y'}; 
    char c[]="I am happy";

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

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

    回过头看代码中对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

  • 相关阅读:
    某图片网站整合yolo图片特征相似图片获取
    MySQL导入数据报错 ERROR 1794 (HY000) at line 22 -- 解决
    apache-commons-lang3之StringUtils使用集锦
    swf格式的flash文件变更md5
    Linux常见场景的shell使用
    tp5在apache下能访问,但放到nginx下报404
    template-web.js 使用二
    jquery实现动态添加html代码
    JQuery的父、子、兄弟节点
    this
  • 原文地址:https://www.cnblogs.com/mrlonely2018/p/11710905.html
Copyright © 2020-2023  润新知