今天在寫父子進程用兩個單向管道通信時,出現了錯誤:
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