2016-04-21 5 views
0

Ich habe tatsächlich Probleme mit einem einfachen Programm, das eine Struktur durch Named Pipes übergeben soll.C++/Gcc - Stack-Zerschlagung, wenn eine Funktion eine Struktur zurückgibt

Hier ist meine main.cpp:

#include <cstdlib>                         
#include <cstdio> 
#include <iostream> 
#include <string> 
#include "NamedPipe.hh" 

int    main()                        
{                              
    pid_t   pid;                         
    std::string str("test_namedPipe");                    
    NamedPipe  pipe(str);                       
    message  *msg;                         

    //Initialisation of my struct                      
    msg = (message *)malloc(sizeof(message) + sizeof(char) * 12);              
    msg->type = 1;                          
    sprintf(msg->str, "Hello World");                     

    //Forking                           
    pid = fork();                          
    if (pid != 0) {                          
    pipe.send(msg);                         
    } else {                           
    message msg_receive = pipe.receive(); //Here is the overflow              
    std::cout << "type: " << msg_receive.type << " file: " << msg_receive.str << std::endl;       
    }                             
    return (0);                           
} 

Mein NamedPipe.cpp:

#include "NamedPipe.hh"                        
#include <stdio.h> 

NamedPipe::NamedPipe(std::string const &_name) : name("/tmp/" + _name) {            
    mkfifo(name.c_str(), 0666);                       
    // std::cout << "create fifo " << name << std::endl;                
} 

NamedPipe::~NamedPipe() {                        
    unlink(name.c_str());                        
} 

void   NamedPipe::send(message *msg) {                  
    int   fd;                         
    int   size = sizeof(char) * 12 + sizeof(message);               

    fd = open(name.c_str(), O_WRONLY);                     
    write(fd, &size, sizeof(int));                      
    write(fd, msg, (size_t)size);                      
    close(fd);                           
} 

message   NamedPipe::receive() {                    
    int   fd;                         
    int   size;                         
    message  msg;                         

    fd = open(name.c_str(), O_RDONLY);                     
    read(fd, &size, sizeof(int));                      
    read(fd, &msg, (size_t)size);                      
    close(fd);                           
    return (msg); //I debugged with printf. This actually reach this point before overflow        
} 

Und ist mein struct definiert wie:

struct       message {                    
    int       type;                     
    char       str[0];                    
}; 

Ich glaube tatsächlich, dass sein ein Problem der Speicherzuweisung, aber ich habe wirklich keine Ahnung, was ich tun soll, um das zu beheben.

Danke fürs lesen/helfen!

+1

Hinweis: 'assert (Größe

+4

Warum benutzen Sie 'malloc' und rohe Zeiger in C++? –

+0

Sie haben Recht, ich habe einen Fehler an dieser Stelle ... Danke für den Hinweis! (Ich bin eigentlich ein c-Programmierer lernen C++) –

Antwort

0

Dies ist die Wurzel des Problems, Ihre struct message:

char str [0];

Dies ist nicht koscher in C++ (noch ist die Art, wie Sie es koscher in C verwenden). Wenn Sie einen message auf dem Stapel zuweisen, reservieren Sie Platz für einen int und 0 char s. Dann in dieser Zeile

read(fd, &msg, (size_t)size); 

schreiben Sie über Ihre Stapelzuweisung in Neverland. Dann geben Sie Ihr message Objekt zurück, das nur eine int Größe wäre.

Ändern Sie Ihre Struktur dazu, und es sollte "Arbeit"

struct message 
    { 
     int type; 
     char str[ 16 ]; 
    }; 
+0

Die "Hallo Welt" hier ist nur ein Beispiel. Ich muss einige variable Str Längen senden –

+0

Egal, was Sie tun, wird nicht funktionieren. So funktioniert Speicher nicht. Was ich gezeigt habe, wird deinen Beispielcode bekommen, um nicht den ganzen Speicher zu zertrampeln, obwohl du auch deine Größenberechnung in deiner Sendefunktion anpassen musst. –