Pregunta

Estoy manteniendo un plugin (implementado como un archivo DLL) para una aplicación de código cerrado grande. Esto ha estado trabajando muy bien desde hace años. Sin embargo, con la última actualización de su SDK el vendedor sobrecargado operadores globales nuevo y borrar. Esto causa muchos problemas para mí. Lo que pasa es que mi complemento asigna una cadena. Paso esta cadena en una biblioteca enlazado estáticamente, que lo modifica (cambia su longitud por lo que la reasignación). Mi aplicación se bloquea.

La razón es, por supuesto, que la cadena vive en el proveedor asignado montón personalizado. La biblioteca enlazado estáticamente sabe nada acerca de este montón y trata de utilizar el valor predeterminado nuevo / borrar los operadores en esa memoria. Boom.

Ahora la cuestión es: ¿cómo puedo mantener mi código limpio y evitar el uso de los operadores del vendedor? No hay ninguna macro preprocesador condicional. No puedo evitar la inclusión de la cabecera del infractor, ya que contiene 2000 líneas más código que necesito para el plugin. No puedo pasar el asignador proporcionada en la otra biblioteca, ya que no proporciona ningún mecanismo para ello. Ya he pinchado el vendedor al respecto. No sé qué más podría intentar?

Adición: Después de un intenso debate que he logrado convencer al proveedor para eliminar las sobrecargas de nuevo de la próxima versión del SDK. He resuelto mi problema inmediato con sólo cortar el SDK actual y la eliminación de las sobrecargas de forma manual. Gracias por todas las sugerencias en este hilo. Ellos sirvieron como argumentos y más "prueba" de por qué las sobrecargas eran una mala idea en primer lugar.

¿Fue útil?

Solución

Si estás compilando en (a través de la inclusión de cabecera) un nuevo sobrescrito / borrar operador (s), a continuación, todas las llamadas en el código para nuevos / borrar los utilizará. No hay manera de volver a anularlo (errores de enlace) o sólo parcialmente anularlo, etc.

Es una mala forma de anular los nuevos operadores globales eliminar /, en absoluto. Es una mala idea. Si no se dan cuenta por qué es una mala idea, no está calificado para hacerlo. Si lo hace darse cuenta de por qué es una mala idea, que está calificado para hacerlo, pero usted generalmente elige no.

La definición de un nuevo mundial / borrar es exponencialmente más mal en un componente esperas que la gente incluyen directamente en su proyecto. Es su trabajo como un cliente para ayudar al proveedor de esta manera entender la gravedad de la situación, o deja de ser su cliente.

Puede definir un tipo de asignador de costumbre (ver este enlace para una buena tutorial sobre cómo hacerlo, la interfaz es necesario, etc) y el uso que exclusivamente con los tipos de STL (es un parámetro de plantilla).

Para shared_ptr, que tiene que hacer algo un poco diferente: se toma un objeto Deleter como parámetro al constructor si no desea que el defecto "borrar p" comportamiento. Esto no es un asignador de costumbre; es sólo un funtor unario regular.

Otros consejos

¿No es posible hacer esto:

namespace evil{

#include "evil_header.h"

}

A continuación, lo evil_header declara como nuevo mundial / eliminar el mal se convierte :: nueva / mal :: eliminar. Dudo que esto va a jugar bien si hay no cabecera definiciones de las cosas declaradas en evil_header sin embargo.

Puede utilizar otro nuevo en el espacio de nombres:

namespace MyNS {
    // Declare your new/delete operators here
    // and also declare a class implementing the same interface as std::allocator
    // using your newly created memory management functions.
    // Don't forget to put all your classes in the namespace.
    // (if you don't have one already)
}

A continuación, puede utilizar todas las clases STL, dándoles el tipo de asignador como parámetro de plantilla.

Una opción es crear su propio nuevo operador sobrecargado que puede ser implementado en términos de malloc.

Esto se podría definir como:

enum MyNew {EMyNew};

void *operator new(size_t size, MyNew);

Esto puede ser llamado por usted como MyClass* myClass = new (EMyNew)MyClass;

Dado que este se implementa en términos de malloc, debería comportarse como se esperaba. La única pega es que usted tendrá que reemplazar todas las instancias de donde se han utilizado nuevos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top