elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Tutorial básico de Quickjs


  Mostrar Mensajes
Páginas: 1 2 3 4 5 6 7 8 9 10 [11] 12 13 14 15 16 17 18 19 20 21 22 23 24
101  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.
102  Programación / Programación C/C++ / Re: Llamar a una funcion de una DLL cargada dinamicamente en: 13 Julio 2021, 16:16 pm
Cierto, me olvidaba de que para x86-64 los parámetros en la pila se alinean a 64 bits.
103  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".
104  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:

Cita de: RayR
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).
105  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í:

Código
  1. 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:

Código
  1. #define TAM_BUFFER 64
  2.  
  3. char nombre_agente[TAM_BUFFER];
  4. ( ...)
  5. write(fd, nombre_agente, TAM_BUFFER);

y haces lo mismo con read. Con eso, siempre estarás leyendo exactamente un único nombre.
106  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.
107  Programación / Programación C/C++ / Re: Semaforos en c en: 16 Mayo 2021, 19:57 pm
Es que así como lo hiciste no hay garantía de ningún orden específico. Y es que ni siquiera es seguro que los hilos se ejecuten en el orden de creación.

No sé si te dieron indicaciones específicas para el ejercicio, pero lo podrías resolver de forma sencilla con tres semáforos. Creas un array de ellos y 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). Esto lo podrías hacer así:

Código
  1. sem_post(&semaphore[(n + 1) % 3 ]);

y para imprimir la letra correcta, algo como:

Código
  1. putchar('A' + n);

También deberías llamar a sem_destroy para destruir los semáforos al final.
108  Programación / Programación C/C++ / Re: cast Void pointer en c en: 26 Abril 2021, 22:57 pm
Es tal como dijo MinusFour. Y C++ va aún más lejos. Los punteros a funciones miembro normalmente son totalmente distintos a los otros, incluyendo los punteros a funciones "normales", no miembro. Por ejemplo, en Visual C++, cuando se usa herencia múltiple, estos punteros ocupan el doble de espacio que los normales (128 bits en programas de 64 bits). La explicación se saldría mucho del tema, pero tiene que ver con que los objetos con varias clases padre tienen más de un puntero this. En GCC (al menos en x86 y x86-64) incluso para objetos sin superclases, los punteros a sus funciones miembro ocupan el doble.
109  Programación / Programación C/C++ / Re: cast Void pointer en c en: 24 Abril 2021, 04:41 am
No dije ser experto, sólo que algo de experiencia sí que tengo. Estoy de acuerdo en que experimentar y equivocarse es indispensable para aprender, aunque normalmente yo trato de señalar cuando algo no es del todo correcto, sobre todo en cuestiones relacionadas con punteros, que puede ser un tema confuso.

Respecto al direccionamiento, eso tambien se lo mencione...
(direccionable dentro de tu programa)

El problema no es si es direccionable o no por el programa. Como había mencionado en otro comentario, aunque es una idea muy extendida, el objetivo de size_t no es almacenar direcciones. Nunca fue creado para eso, y de hecho, existen plataformas donde tiene un tamaño menor a un puntero, por lo que es totalmente posible, y probable, tener variables cuyas direcciones no pueden ser almacenadas en un size_t. Eso es válido, ya que la especificación de C dice expresamente que aunque un puntero puede convertirse a cualquiera de los tipos enteros (incluyendo size_t), puede no caber, y que en ese caso, el comportamiento del programa queda indefinido. En la práctica, en casi todas las arquitecturas actuales sí tiene el tamaño suficiente, y por eso no es tan raro almacenar direcciones en variables enteras (aunque normalmente se usa directamente el long o unsigned long), sin embargo, no hay garantías. Por eso se incorporaron a C los tipos opcionales intptr_t y uintptr_t, los únicos con los que es seguro almacenar punteros (siempre que no sean punteros a funciones). Por cierto, tampoco se requiere que size_t tenga el tamaño de una palabra, aunque eso es lo habitual.

De hecho, lo que si que no se es hasta que punto size_t* puede direccionar la memoria. ¿Hablas del caso en que una direccion contenga ademas un segmento?

size_t* puede direccionar la memoria, como el resto de punteros, aunque aquí también, C dice que punteros a diferentes tipos pueden tener tamaños distintos, por lo que en teoría sólo deberían apuntar a memoria donde haya un valor size_t. Claro que en la realidad es prácticamente seguro que todos los punteros tengan el mismo tamaño, exceptuando, otra vez, los punteros a funciones. Ni siquiera void* es válido para apuntar a funciones. Para eso únicamente se deben usar punteros a funciones. Y por supuesto, desreferenciar un puntero que apunta a un dato cuyo tipo no es el mismo que el del puntero es arriesgado. No sólo puede haber problemas de alineación o tamaño, sino que a veces los compiladores, apegándose a lo que dicen las reglas, hacen optimizaciones que rompen código que accede a direcciones por medio de punteros a tipos distintos. Según su rígida interpretación, dado que un puntero de tipo A "no puede" apuntar a un valor de un tipo distinto a A, el compilador no está obligado asegurar que ese acceso se produzca correctamente, y si se rompe algo, toda la culpa es del programador. Eso ha pasado con el kernel Linux, por ejemplo, y hay mucho debate al respecto.

Lo de memorias con segmentos es un ejemplo. En el caso de DOS de 16 bits, para modelo large, por ejemplo, típicamente size_t es de 16 bits, pero los punteros ocupan 32. En este caso específico (x86) sí sería porque contienen segmentos, pero aún en ausencia de segmentación, otras arquitecturas pueden tener punteros más grandes que size_t por motivos diferentes.
110  Programación / Programación C/C++ / Re: cast Void pointer en c en: 22 Abril 2021, 15:35 pm
Eso de experto lo dije porque esta frase:

Código
  1. ¿Al menos sabes por qué la solución que le di le funcionó?:

me había sonado un poco condescendiente, como si fuera demasiado complicado para que alguien (yo) lo entendiera. En fin.

Sólo puntualizar una cosa. No es que almacenar el valor de un puntero en un entero como size_t esté mal en sí. Como había dicho antes, a veces se hace; la propia API de Windows es un ejemplo. Pero aunque en todos los sistemas actuales size_t es lo suficientemente grande para guardar direcciones, no hay garantía de que siempre sea así, y en los casos donde no lo sea, el resultado quedaría indefinido (por ejemplo, en DOS de 16 bits, el programa seguramente no funcionaría correctamente, al menos si se compila para modelo compact, large, etc.) por lo que, si no es estrictamente necesario no se debería hacer.
Páginas: 1 2 3 4 5 6 7 8 9 10 [11] 12 13 14 15 16 17 18 19 20 21 22 23 24
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines