|
101
|
Programación / Programación C/C++ / Re: Puntero doble
|
en: 15 Agosto 2021, 18:46 pm
|
Aquí también tienes un error: (*nuevo_elemento)->contenido.DNI = nuevoDato->DNI; porque reservaste memoria para nuevo_elemento, pero no para *nuevo_elemento, por lo que este último es un puntero sin inicializar, así que en la línea anterior estás escribiendo en quién sabe que dirección. Antes tienes que hacer algo como esto: *nuevo_elemento = (COLA)malloc(sizeof(tCola)); De todas formas, piensa bien si de verdad necesitas tantas indirecciones. Puedes pasar variables por puntero/referencia sin usar realmente un puntero, simplemente usando el operador &. Fíjate a ver si puedes simplificar tu programa.
|
|
|
102
|
Programación / Programación C/C++ / Re: fread modifica algunos bytes tratando de volcar parte de un archivo en otro
|
en: 10 Agosto 2021, 03:01 am
|
No probé el programa, pero tienes un error en la línea 62: GENERATED_IV = IV;
IV es local a la función cipherBlock, por lo que sólo existe dentro de ella (de hecho, dentro del bloque if donde fue declarada) de manera que al retornar de esa función, GENERATED_IV apunta a una dirección inválida. Es de esas cosas que a veces funcionan por casualidad pero son un error. Probablemente eso es lo que te ocasiona el problema. También por ahí reservas memoria sin liberarla pero eso aquí sólo gasta memoria y no es la causa del error. Añado: lo más simple sería que hagas GENERATED_IV un arreglo de tamaño fijo.
|
|
|
103
|
Programación / Programación C/C++ / Re: error en tiempo de ejecucion en programa c++
|
en: 8 Agosto 2021, 21:26 pm
|
gracias para empezar soy nuevo en linux, a que funciones especificas te referis, y por otra parte, estamos de acuerdo que esa zona de memoria igual que la 0xA0000000, siguen existiendo?, si es asi no hay ninguna manera de romper esa barrera sin dañar al SO?
Esas direcciones en sí no tienen nada de especial, es simplemente que bajo DOS, ahí se mapeaba la VRAM. Escribir en esas direcciones para modificar los pixeles o caracteres sólo tiene sentido bajo DOS o algún SO compatible, y con la tarjeta de video corriendo en modo EGA, VGA, etc. De todas formas los sistemas modernos usan memoria virtual, por lo que la dirección 0xb8000000 que ve tu programa no se corresponde con la dirección física 0xb8000000 en la RAM. Además, en general no permiten acceder directamente al hardware a los programas normales. TL;DR: no se puede de esa manera. BloodSharp ya te dio algunas opciones con las que lo podrías hacer.
|
|
|
104
|
Programación / Programación C/C++ / Re: error en tiempo de ejecucion en programa c++
|
en: 8 Agosto 2021, 16:26 pm
|
Como te dijo BloodSharp , eso es para el viejo DOS. No sirve para sistemas operativos modernos, por muchas razones. Que te funcionara en Windows se explica porque las versiones de 32 bits incluyen (o por lo menos así era antes) una máquina virtual de DOS para los programas de 16 bits, por lo que si el ejecutable fue generado con un compilador de 16 bits, y lo abres en esas versiones de Windows, va a funcionar, aunque de forma emulada, no nativa. Si de todas formas te interesa programar de esa manera por curiosidad, puedes instalar el emulador DOSBox, que tiene versiones para Windows y Linux, pero lo mejor es que simplemente uses funciones específicas del SO.
|
|
|
105
|
Programación / Programación C/C++ / Re: Es seguro reemplazar el paso de parametros por valor, utilizando punteros a constantes ?
|
en: 30 Julio 2021, 21:12 pm
|
Aunque se puede, no tiene caso hacerlo con tipos básicos, como te dijo ivancea96. De hecho, aparte de los inconvenientes que él te menciona, también está el hecho de que ya no podrías pasarle constantes literales; además de que lo que leíste en el libro sólo aplica si los parámetros son objetos grandes, como estructuras. Ahí se justifica pasar por puntero porque es más eficiente copiar un único valor de 32 o 64 bits, que todos los campos de una estructura o clase, (por no hablar de las llamadas a constructores que se llevarían a cabo si hablamos de C++), por más que el compilador pueda hacer optimizaciones que lo hagan menos ineficiente.
Pero si hablamos de tipos simples, como int, el paso por puntero es de hecho menos eficiente. Dado que el parámero que la función recibe es sólo una dirección, antes de acceder al valor en sí, hay que ir a buscarlo a la memoria, lo cual no sucede con el paso por valor.
En resumen, a menos que se trate de objetos grandes, no tiene sentido pasar punteros a funciones que no necesitan modificar los parámetros. Eso sólo hace tus funciones menos legibles, menos seguras, menos flexibles y menos eficientes.
|
|
|
107
|
Programación / Programación C/C++ / Re: Llamar a una funcion de una DLL cargada dinamicamente
|
en: 13 Julio 2021, 04:00 am
|
En general, no le deberías pasar a una función argumentos de tipos distintos a los que espera de la manera en que lo estás haciendo (o sea, mediante puntero a función con cast en los parámetros). Independientemente de cómo los interprete, el verdadero problema es que los tamaños podrían ser diferentes. Por ejemplo, el tercer parámetro de WriteConsole es de tipo DWORD, que ocupa 32 bits, pero al hacer el cast a int64_t le estarías pasando 64. En este caso imagino que funciona, pero es casi por casualidad. Estás compilando para 64 bits, por lo que los primeros 4 argumentos se van a pasar en registros. Como son independientes, no tienes problemas, pero si se pasaran en la pila, podría fallar. Esto pasaría si intentaras hacerlo en programas de 32 bits, o llamar funciones que reciban más parámetros. Por darte un ejemplo, no podrías llamar de manera confiable a CreateProcess, ni siquiera en 64 bits.
Imagino que lo estás haciendo para practicar, y está bien, pero obviamente, no sería buena idea hacer algo así en algo más "formal".
|
|
|
108
|
Programación / Programación C/C++ / Re: Semaforos en c
|
en: 25 Junio 2021, 15:27 pm
|
El planteamiento es correcto. Pero es importante resaltar el valor inicial de los semáforos. Todos a 0, menos el primero, a 1.
¿¿¿??? Pues eso es lo que puse en mi mensaje: el primero lo inicializas a 1, y los otros a 0. A cada hilo le podrías enviar como parámetro entero su número de índice. Cada hilo "n" espera por el semáforo n, e incrementa (sem_post) el semáforo n + 1, a excepción del último (2), que incrementará el primero (0).
|
|
|
109
|
Programación / Programación C/C++ / Re: Sincronización de procesos
|
en: 25 Mayo 2021, 01:10 am
|
Ese código tiene toda la apariencia de haber sido copiado de algún lado. No lo hagas, o vas a tener muchos problemas para entender estos temas. Tu programa no funciona como multihilo, ya que, si a cada create le sigue inmediatamente un join, estás forzando a que se ejecute de forma secuencial. De todas formas, si, como planteas en tu pregunta, quieres que el controlador atienda un agente a la vez, no tiene sentido querer usar hilos. Mejor llama directamente a routineRead y routineWrite. Omitiste demasiado código, pero parece que dentro del segundo do while usas un pipe distinto por cada proceso, como debe ser. Sin embargo, parece que al principio (línea 11 del último código) el controlador abre un pipe predefinido mediante el cual todos los agentes le envían su nombre, que luego usará para crear fifos para comunicarse con cada proceso. El problema sería que más de un proceso puede escribir en el pipe predefinido antes de que el controlador lo lea, así que cuando finalmente éste lo lee, recibe varios juntos. Primero, el hecho de que se muestren pegados por pantalla indica que no estás enviando cadenas completas (cerradas), lo cual puede causar problemas de memoria. Si en el agente tienes algo así: write (fd , nombre_agente , strlen(nombre_agente ));
cambia el último parámetro a strlen(nombre_agente) + 1, para que también se envíe el caracter nulo. Con esto estarás mandando cadenas correctas, pero todavía queda el problema original. La cuestión es que lo que hagan los procesos externos está, en general, fuera de tu control. Quizás lo mejor sería usar otro mecanismo (no pipes) para ese intercambio original de información, los nombres de agentes y pipes. Pero si lo quieres/tienes que hacer con pipes, lo que necesitas es delimitar de alguna forma cada mensaje. Lo más sencillo es que cada mensaje enviado al pipe predefinido (el que usas al principio para enviar el nombre del agente) sea de un tamaño fijo. Por ejemplo: #define TAM_BUFFER 64 char nombre_agente[TAM_BUFFER]; ( ...) write(fd, nombre_agente, TAM_BUFFER);
y haces lo mismo con read. Con eso, siempre estarás leyendo exactamente un único nombre.
|
|
|
110
|
Programación / .NET (C#, VB.NET, ASP) / Re: Se puede dar Privilegios de Administrador a un segmento de código en especifico?
|
en: 18 Mayo 2021, 02:41 am
|
Hasta donde sé, no es posible. Al menos no sin tener que reiniciar la aplicación. Lo que se podría hacer es crear algún objeto COM y llamarlo con privilegios elevados, que debe ser a lo que te refieres con CoCreateInstanceAsAdmin, aunque tendrías que lidiar con toda la parafernalia e inconvenientes de COM. Otra opción sería crear un proceso que ejecute las tareas que requieran elevación de privilegios y llamarlo desde el primero, y comunicarlos usando alguno de los mecanismos IPC de Windows, como pipes o sockets.
|
|
|
|
|
|
|