2010-09-01 24 views
5

El programa en el que estoy trabajando falla a veces tratando de leer datos en la dirección 0xCCCCCCCC. Google (y StackOverflow) siendo mis amigos, vi que es el código de depuración de MSVC para la variable de pila no inicializada. Para entender de dónde viene el problema, traté de reproducir este comportamiento: el problema es que no he podido hacerlo.Cómo terminar con un puntero a 0xCCCCCCCC

La pregunta es: ¿tiene un fragmento de código que muestra cómo un puntero puede terminar apuntando a 0xCCCCCCCC?

Gracias.

+2

¿Ha inicializado todos sus punteros a un valor conocido? –

+0

@In silico +1, no estoy seguro de cuál es la pregunta aquí ... – synhershko

Respuesta

5

Compila tu código con /GZ compiler switch o /RTCs switch. Asegúrese de que /Od switch también se usa para deshabilitar cualquier optimización.

s

Habilita marco de pila comprobación de errores de tiempo de ejecución, como sigue:

  • de inicialización de las variables locales a un valor distinto de cero. Esto ayuda a identificar errores que no aparecen cuando se ejecuta en modo de depuración. Hay una mayor probabilidad de que las variables de pila sigan siendo cero en una compilación de depuración en comparación con una compilación de lanzamiento debido a las optimizaciones del compilador de las variables de pila en una compilación de lanzamiento. Una vez que un programa ha utilizado un área de su pila, el compilador nunca lo restablece a 0. Por lo tanto, las variables de pila subsiguientes no inicializadas que utilizan el mismo área de pila pueden devolver valores que quedaron del uso anterior de esta memoria de pila.

  • Detección de sobrepasos y subutilizaciones de variables locales como matrices./Los RTC no detectarán excesos al acceder a la memoria que resulta del relleno del compilador dentro de una estructura. El relleno podría producirse mediante el uso de alineación (C++),/Zp (Alineación de miembro de Struct) o paquete, o si ordena elementos de estructura de tal manera que requiera que el compilador agregue relleno.

  • Comprobación del puntero de la pila, que detecta la corrupción del puntero de la pila. La corrupción del puntero de pila puede ser causada por una discrepancia de convención de llamadas. Por ejemplo, al usar un puntero de función, llama a una función en una DLL que se exporta como __stdcall pero declara el puntero a la función como __cdecl.

9
int main() 
{ 
    int* p; 
} 

Si se construye con el tiempo de ejecución de depuración de Visual C++, poner un punto de interrupción en main(), y correr, se verá que p tiene un valor de 0xcccccccc.

+0

Eso es lo que pensé, pero no, solo tengo un valor aleatorio no inicializado. – gregseth

+0

Jim es correcto. – EvilTeach

2

No tengo MSVC, pero este código debería producir el problema y compilar sin advertencias.

En f1.c archivo:

void ignore(int **p) { } 

En f2.c archivo:

void ignore(int **p); 
int main(int c, char **v) 
{ 
    int *a; 
    ignore(&a); 
    return *a; 
} 

La llamada a ignore hace que parezca que a podría ser inicializado. Dudo que el compilador advierta en este caso, debido al riesgo de que la advertencia sea un falso positivo.

+1

En Visual C++ 2008 y 2010, este código exacto genera el nivel 1 de advertencia C4700: "variable local no inicializada 'a' utilizada". Tendría que tener 'ignorar' tomar un puntero o una referencia a' int * 'para que exista la posibilidad de que' a' sea inicializado por la llamada a 'ignorar'. –

+0

¿Puede explicar el riesgo de un falso positivo? – Tomas

+0

No hay advertencia y no hay 0xCC ... direcciones en mi computadora. ¿Hay opciones de compilación especiales para habilitar la función? – gregseth

0

¿Qué tal esto? Ignore la advertencia que lanza VC mientras se ejecuta.

struct A{ 
    int *p; 
}; 

int main(){ 
    A a; 
    cout << (void *)a.p; 
} 
Cuestiones relacionadas