0

I am trying to build a CORBA application, which has the following IDL interface:

module Chat {
exception SesionNoIniciada{};
exception UsuarioNoRegistrado{};
exception ErrorServidor{};
exception SesionYaIniciada{};

interface Cliente{
    readonly attribute string nombre;

    oneway void nuevaSolicitudDeAmistad(in string c); //devuelve void, parametro string/char*
    oneway void actualizarListaAmigos();
    oneway void nuevoMensaje(in Cliente usuario, in string men);
};

typedef sequence<string> nombres;
typedef sequence<Cliente> clientes;

interface Servidor{
    nombres iniciarSesion(in Cliente usuario, in string pass) raises (UsuarioNoRegistrado, SesionYaIniciada);
    void cerrarSesion(in Cliente usuario, in string pass) raises (SesionNoIniciada);

    nombres getUsuariosRegistrados(in Cliente usuario, in string pass, in string nombre) raises (SesionNoIniciada);
    nombres getAmigos(in Cliente usuario, in string pass) raises (SesionNoIniciada);
    clientes getAmigosConectados(in Cliente usuario, in string pass) raises (SesionNoIniciada);
    void nuevaSolicitudDeAmistad(in Cliente amigo1, in string pass, in string amigo2) raises (UsuarioNoRegistrado, SesionNoIniciada);
    void aceptarSolicitudDeAmistad(in Cliente amigo1, in string pass, in string amigo2) raises (UsuarioNoRegistrado, SesionNoIniciada);
    void rechazarSolicitudDeAmistad(in Cliente amigo1, in string pass, in string amigo2) raises (UsuarioNoRegistrado, SesionNoIniciada);
    void eliminarAmistad(in Cliente amigo1, in string pass, in string amigo2) raises (UsuarioNoRegistrado, SesionNoIniciada);
};
};

The following method is giving me a segmentation fault in the return line:

nombres* Servidor_i::getAmigos(Cliente_ptr usuario, const char* pass){

vector<string> aux;
nombres_var result;
Cliente_ptr cliente;

try{
    aux=bd.listarAmigos(usuario->nombre()); //Gets names from DB (currently 0)
    result = new nombres(aux.size());
    for(int i=0; i<aux.size(); i++) //This for is not being executed, since size is 0
        result[i] = aux.at(i).c_str();
} catch(ErrorBD& e){
    throw ErrorServidor();
}
cout << "Ending" << endl;
return result._retn();
}

I think it will be something related to dynamic memory freeing, but I am not used to CORBA yet, so I'm not sure if I am using the data types in a proper way.

user3407000
  • 188
  • 2
  • 10
  • By the way, I have tried manually initializing result right before the return sentence and I can print its contents (I have tried with a couple of strings). – user3407000 Apr 07 '14 at 18:01
  • what is definition of type 'nombres_var'? – Matt Apr 07 '14 at 18:04
  • It is an automatically generated data type from the sequence defined in the IDL interface. I am using OmniORB, by the way. – user3407000 Apr 07 '14 at 18:07
  • So what is the intention of this line: `result = new nombres(aux.size());`? Is it to declare a dynamic array of aux.size() nombres? If so, that line of code does not do what you think it does. – PaulMcKenzie Apr 07 '14 at 18:12
  • Sorry, I don't use CORBA. If you can find out the definition of 'sequence" and 'nombres_var', I think that could help to solve the problem – Matt Apr 07 '14 at 18:13
  • @PaulMcKenzie I want to return nombres, as the interface says. The automatic mapping to C++ tells me that my functions should return 'nombres*'. I just want to return a sequence of strings and I am not quite sure of how to do it in CORBA. I have tried to put it in my nombres_var variable, but that does not seem to be working. Sorry about being so inexpert on the topic. – user3407000 Apr 07 '14 at 18:18
  • @Matt They are CORBA types, so if you are not used to CORBA I don't think you can help. Thanks anyway. – user3407000 Apr 07 '14 at 18:20
  • @user3407000 - Forget CORBA for a moment. Do you want to create an array of nombres_var types? Simple question, it's either yes or no. If it's yes, that's where your problem is. – PaulMcKenzie Apr 07 '14 at 18:24
  • @user3407000 - In other words, do you know the difference between: `int *p = new int [10];` and `int *p = new int (10);`? That's what I'm trying to get you to respond to. – PaulMcKenzie Apr 07 '14 at 18:29
  • @PaulMcKenzie I want to create a 'nombres*' variable that I can return. I thought this was to be assigned to a 'nombres_var' variable in order to be remotely returned (so that CORBA manages the number of references on it). The point is that I don't know how to return a sequence of strings in CORBA, and it is all I need to do, I don't care how. Any explanation on this would be very much appreciated, even if it does not strictly relate to my code above. – user3407000 Apr 07 '14 at 18:30
  • @PaulMcKenzie Ah, now I understood your question. I do understand the difference. What I want to do is to use a constructor of nombres and assign the resulting value to nombres_var, but I am not sure this is the way to proceed. – user3407000 Apr 07 '14 at 18:31
  • @user3407000 - You are using result[i] in the very next line. That indicates to me that you are supposed to allocate an array. If that is the case, then you're supposed to be using array new (new[]), not new( ). If you told us what nombres_var exactly was in C++ (we don't need to know what technology it comes from), we would be able to answer your question. – PaulMcKenzie Apr 07 '14 at 18:33
  • @PaulMcKenzie I think CORBA has overridden the [] operator to return values, but it does not mean it is an array of nombres_var. – user3407000 Apr 07 '14 at 18:35
  • @user3407000 - Then there is something strange about that function. You are saying that result is a nombres_var, but you are using the new( ) operator to create a single nombre. It would make more sense if it were this: `result = new nombres_var(aux.size());` – PaulMcKenzie Apr 07 '14 at 18:38
  • @PaulMcKenzie But nombres_var does not have a constructor that allows to specify its length: you can pass it a nombres* object instead, and that's why I have tried what you see on the code above. Anyway, if I use the nombres_var(nombres*) constructor, I can create a nombres_var propperly and print its values, the problem comes when I want to return it remotely, so it is completely CORBA-related I guess (when it tries to free unused references). I know I am doing it in a wrong way, but I don't know why. – user3407000 Apr 07 '14 at 18:45
  • @user3407000 - Then CORBA uses a very unintuitive interface. Here we see you declaring a nombres_var named result. This must be a pointer type, else the code would not compile at the call to new. But the call to new uses ( ), which means it creates a `single` nombre, and initializes it with aux_size. Then to add to that, your return type is nombres*, but instead of just returning "result" (which is a nombres*, else the code would not compile), you're returning the return value of the result._retn() function. – PaulMcKenzie Apr 07 '14 at 18:51
  • @user3407000 - So what would this create? `nombres_var result(25);`? Does it create a single nombres_var that can hold 25 strings? – PaulMcKenzie Apr 07 '14 at 18:55
  • @PaulMcKenzie It is indeed not an intuitive interface, that's why I am so confused. Besides, there is very little help on the Internet, since CORBA seems to be in disuse nowadays, but I have to use it for a class project, so I am stuck. All I know is that ._retn() is for returning objects remotely. – user3407000 Apr 07 '14 at 18:55
  • http://stackoverflow.com/questions/11938070/ptr-or-var-which-one-use-as-a-class-field-and-why, nombres_var is a smart pointer type, like auto_ptr, I think – Matt Apr 07 '14 at 19:00
  • @PaulMcKenzie Yes, it does. – user3407000 Apr 07 '14 at 19:02
  • @Matt Yes, but it does some memory freeing that is causing a segmentation fault. I have tried to use a nombres_ptr, but my ORB manager has not generated such a data type. – user3407000 Apr 07 '14 at 19:06
  • I don't see anything obviously wrong. The code looks correct from a CORBA IDL to C++ mapping perspective. I don't think there is anything wrong with creating a string sequence of size zero. Perhaps there is some other problem in your program that is corrupting the heap elsewhere and it is just getting triggered here. – Brian Neal Apr 07 '14 at 19:36
  • @PaulMcKenzie You'll have to digest the CORBA IDL to C++ mapping document to fully understand the _var types. They are a set of smart pointer like types that predate the STL. They are confusing and not intuitive. There is a newer C++11 mapping which is far better but it is not widely supported yet. – Brian Neal Apr 07 '14 at 19:41
  • TAOX11 supports the new C++11 mapping, it has free evaluation licenses – Johnny Willemsen Apr 07 '14 at 19:56
  • Have you tried to run with for example valgrind, when the loop is not executed the code does look ok – Johnny Willemsen Apr 07 '14 at 20:09
  • @JohnnyWillemsen I don't think that changing my ORB manager is now an option in the middle of the project. If I have any other chance of fixing my program, I will do it, but thanks for the suggestion. By the way, I don't know what valgrind is. – user3407000 Apr 07 '14 at 21:53
  • valgrind is a tool you can use to find memory issues. – Brian Neal Apr 07 '14 at 23:41
  • @user3407000 Maybe TAOX11 would be an option for the next project, maybe something to mention to your teacher – Johnny Willemsen Apr 08 '14 at 07:26

1 Answers1

0

Since it was impossible for me to find out what was wrong with my code, and generating the segmentation fault I have spoken about; I thought of an alternative way in which I could solve my problem: I have rebuilt the IDL interface so that the function has an 'out' parameter which allows me to return a sequence without any kind of problem.

user3407000
  • 188
  • 2
  • 10