ver vacio vacia una saber que objeto nulo not esta ejemplo declared declarar como cadena arreglo c++ null pointers memset

c++ - vacio - cómo establecer el puntero a una memoria a NULL usando memset?



objeto nulo c++ (9)

¿Qué estás tratando de hacer exactamente? p_my_t ya es un puntero, pero no ha asignado memoria para ello. Si desea establecer el puntero a NULL, simplemente haga

p_my_t = NULL;

Intentar desreferenciar este puntero dará como resultado una falla de segmentación (o una infracción de acceso en Windows).

Una vez que el puntero realmente apunta a algo (por ejemplo, a través de malloc() o asignándole la dirección de una struct my_T ), entonces puedes correctamente memset() :

memset(p_my_t, 0, sizeof(struct my_T));

Esto pondrá a cero toda la estructura, estableciendo todos los campos a cero.

Tengo una estructura

typedef struct my_s { int x; ... } my_T; my_t * p_my_t;

Quiero establecer la dirección de p_my_t en NULL y hasta ahora, así es como he intentado hacer esto:

memset (&p_my_t, 0, sizeof(my_t*))

Aunque esto no me parece bien. ¿Cuál es la forma correcta de hacer esto?

Enmienda a la pregunta: hacer una pregunta radicalmente más compleja :

Esto es lo que estoy tratando de hacer:

  • Dos procesos, A y B
  • malloc p_my_t en A, B tiene N hilos y puede acceder a él
  • Comience a eliminar en A, pero no puedo simplemente liberarlo ya que los hilos en B aún pueden usarlo.
  • Así que llamo a una función, paso la dirección de p_my_t a B para establecer su dirección a NULL en B por lo que no hay otros hilos en B pueden usar más
  • Después de volver a llamar desde B, entonces guardo memoria en A

NB: no hay una forma estándar de administrar las asignaciones de memoria a través de la memoria compartida entre procesos. Tendrás que pensar un poco cuidadosamente sobre lo que está pasando.


El código recomendado para establecer un puntero a nulo es asignar 0 (cero). Bjarne Stroustrup lo hace :) De todos modos es tan expresivo como NULL y no depende de una definición de macro.

Tenga en cuenta que NULL no es una palabra clave, no está reservado y, aunque sería confuso redefinir, nada dice que no deba (más que estilo). Un compañero de trabajo a menudo bromea sobre la definición de NULL a algo diferente a 0 en un encabezado solo para ver cómo se comporta el código de otras personas.

En el próximo estándar habrá una palabra clave nullptr más expresiva para identificar un puntero nulo.


Gracias, esto es lo que trato de hacer

  • dos procesos, A y B
  • malloc p_my_t en A, B tiene N hilos y puede acceder a él
  • empiezo a eliminar en A, pero no puedo simplemente liberarlo ya que los hilos en B aún pueden usarse.
  • así que llamo a una función, paso la dirección de p_my_t a B para establecer su dirección a NULL en B, por lo que no hay otros hilos en B que puedan usar más
  • Después de volver a llamar desde B, entonces guardo memoria en A

Según su respuesta (en otro lugar de esta publicación) indicando:

Gracias, esto es lo que trato de hacer

  • dos procesos, A y B
  • malloc p_my_t en A, B tiene N hilos y puede acceder a él
  • empiezo a eliminar en A, pero no puedo simplemente liberarlo ya que los hilos en B aún pueden usarse.
  • así que llamo a una función, paso la dirección de p_my_t a B para establecer su dirección a NULL en B, por lo que no hay otros hilos en B que puedan usar más
  • Después de volver a llamar desde B, entonces guardo memoria en A

Lo que necesita es alguna forma de sincronización entre todos sus hilos y procesos. No estoy seguro de cómo está compartiendo este objeto entre los procesos, pero sospecho que está utilizando la memoria compartida.

Normalmente recomendaría usar una clase de punteros compartida (como la clase shared_ptr de Boost), pero no estoy seguro de qué tan bien funcionaría en este escenario. Es posible que desee considerar modificar su clase para que rastree sus propias referencias y pueda usarse con la clase intrusive_ptr Boost.

De esta forma, el proceso A simplemente puede olvidarse del objeto, y cuando finaliza el proceso B, la instancia de my_T sabrá que ya no quedan más referencias y se limpiará a sí mismo.

La sincronización entrará en juego aquí cuando my_T esté agregando o eliminando referencias internamente (para que no se encuentre con desagradables condiciones de carrera donde cree que debería limpiarse, pero que todavía está en uso).

Otro enfoque que tiene un poco más de sensación de "kluge" es dar a cada instancia de my_T un my_T "is-valid" para que todos los procesos / hilos que lo usan sepan si continúan o no haciéndolo.

Para obtener más detalles sobre las distintas clases de punteros de Boost, consulte su documentación .


Creo que tal vez quieras

extern void set_t_pointer_to_null(my_T *pp);

y llama

set_t_pointer_to_null(&p_my_t);

dónde

void set_t_pointer_to_null(my_T *pp) { *pp = NULL; }

No estoy seguro de que valga la pena definir una función para hacer esto, pero creo que esto responde la pregunta que intentas hacer.


Después de leer sus comentarios de múltiples hilos, debo decir que no hay una secuencia de código segura para llevar a cabo su tarea. Tendrá que dar un paso atrás y volver a examinar su algoritmo.


No use memset para inicializar un puntero nulo ya que esto configurará la memoria en todos los bits cero, lo que no garantiza que sea la representación de un puntero nulo, simplemente haga esto:

p_my_t = NULL;

o el equivalente:

p_my_t = 0;


Según su actualización, me parece que lo que realmente está tratando de hacer es proteger el acceso a un recurso, lo que significa que debe usar un bloqueo de lectura / escritura compartido entre los procesos para proteger el ptr de ese recurso, y probar el ptr antes de usar.

  • Asigna la estructura en la memoria compartida.
  • Asigna el ptr a la estructura en la memoria compartida.
  • Guarde el acceso al ptr a la estructura con un bloqueo de lectura / escritura.
  • El proceso A debe adquirir un bloqueo de ESCRIBIR al ptr al inicializar o invalidar el ptr y la estructura.
  • El proceso B debe adquirir un bloqueo de LECTURA en el ptr, y probar que el ptr es válido antes de usar la estructura

Si lo hago bien, memset no resolverá tu problema. Si A y B son procesos separados, entonces p_my_t en el proceso A será diferente de p_my_t en el proceso B. Simplemente no puede pasar un puntero entre diferentes procesos. Supongo que usas algún tipo de mecanismo de IPC para sincronizar tus dos procesos (colas de mensajes, por ejemplo), y simplemente usando p_my_t = NULL lugar de memset.