2017-01-04 69 views
0

即時寫入和從共享內存中讀取字符串。 這裏it's我的代碼:Linux-C從共享內存中讀取已損壞的數據

這是作家(我已經中省略無關的代碼)

int main() { 

    char message[MAX_BUF]; 
    key_t key; 
    int sharedMemoryId; 
    int semaphoreId; 
    char *vc1; 
    char *data; 
    pid_t p3; 
    struct sembuf operations[1]; 

    printf("start p2\n"); 

    saveMesageInBuffer(message); //This reads message from pipe and saves into message variable 

    if(message==NULL){ 
     return -1; 
    } 

    key = getKeyForFile(); 

    if(key != -1){ 

     sharedMemoryId = createSharedMemoryId(key); 
     if(sharedMemoryId!=-1){ 
     vc1 = shareContentInMemoryId(sharedMemoryId); 
     } 

     switch(p3 = fork()){ 
     case -1: 
      printf("Error"); 
      break; 
     case 0: 
      printf("run\n"); 
      execl("./Ej3", "Ej3", NULL); 
      break; 
     default: 
      sleep(SECONDS); 
      writeMessageInSharedVariable(vc1, message); 
      pause(); 
      break; 
    } 

    } else { 
     printf("Error getting key for file: %s\n", strerror(errno)); 
    } 

    return 0; 
} 

void writeMessageInSharedVariable(char *dest, char *message){ 
    printf("El proceso P2 (PID=%d, Ej2) transmite un mensaje al proceso P3 a traves de una variable en memoria compartida\n", getpid()); 
    strncpy(dest, message, MAX_BUF); 
} 

int createSharedMemoryId(key_t key){ 
    return shmget(key, MAX_BUF, IPC_CREAT | 0600); 
} 

char* shareContentInMemoryId(int memoryId){ 
    return shmat(memoryId, (void *)0, 0); 
} 

key_t getKeyForFile(){ 
    char filePath[1024]; 
    if (getcwd(filePath, sizeof(filePath)) != NULL){ 
     strcat(filePath, "/"); 
     strcat(filePath, FIFO_FILE_NAME); 
     return ftok(filePath, 0777); 
    } else { 
    return (key_t) -1; 
    } 
} 

`

這是讀者(編譯爲EJ3並通過fork和exec從推出作家)

int main() { 
    key_t key; 
    char message[MAX_BUF]; 
    int sharedMemoryId; 
    char* vc1; 

    printf("el 33 \n"); 

    key = getKeyForFile(); 
     if(key != -1){ 
     sharedMemoryId = createSharedMemoryId(key, sizeof(message)); 
     sleep(3); 
     printf("continua\n"); 
     vc1 = (char*)shmat(sharedMemoryId, (void *)0, 0); 
     if (vc1 == (char *)(-1)) { 
      perror("shmat"); 
      exit(1); 
     } 
     printf("Readed %s\n", vc1); 

    } else { 
     printf("Error getting key for file: %s\n", strerror(errno)); 
    } 

} 

我正在寫郵件的測試,這是我讀它的結果。

Readed測試[]瓦特

+3

顯然你缺少終止零。所以它沒有被「損壞」。 – usr2564301

+0

對不起,我不理解你喲 – colymore

+3

@colymore'%s'格式用於打印一個C字符串,它是一個以空字節結尾的字節數組。你並沒有在共享內存中的字符串末尾放置空字節,所以你在後面打印垃圾。 – Barmar

回答

3

strncpy(dest, message, MAX_BUF);

strncpy doesn't null-terminate the buffer。 你必須自己終止它。

strncpy(dest, message, MAX_BUF); 
dest[MAX_BUF-1] = '\0'; /* <- like this */ 

printf(%s需要C字符串,它是一個字符數組,最後是一個空字符。如果你沒有空字符串終止,printf將不知道什麼時候停止,從而垃圾輸出。