c++ - new - que es string en java
Después de p=new string[0] yp=new int[0], ¿por qué la versión de cadena falla cuando delete[] p? (1)
Tengo dos bloques de código sobre new[]
y delete[]
:
1)
#include <string>
int main()
{
std::string *p = new std::string[0];
delete[] p;
return 0;
}
2) En este caso, simplemente cambio std::string
a int
int main()
{
int *p = new int[0];
delete[] p;
return 0;
}
Mi pregunta es:
Por qué el primer programa falla con el siguiente mensaje (en entorno Linux):
Segmentation fault (core dumped)
Pero el segundo programa funciona bien sin ningún error?
EDITAR
compilador: g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
Solo uso g++
sin ningún argumento para compilarlo.
Si se trata de un error del compilador, ¿deberían fallar o no según el estándar?
Esto debería ser un error de gcc. Que toda la new[]
expresión new[]
se ignora y p
se desinicializa, y luego eliminamos delete[]
un puntero no inicializado que se bloquea. Si -Wall
el programa con -Wall
te advertirá que
advertencia: ''p'' se usa sin inicializar en esta función
lo cual es claramente incorrecto La expresión new X[0]
está bien definida tanto en C ++ 03 como en C ++ 11 (§5.3.4 / 7), y esto funciona correctamente en clang, por lo que la única conclusión lógica es que se trata de un error de gcc.
El error de eliminación de new[]
solo existe cuando el tipo que se construye tiene un constructor no trivial. Y ocurre el segfault, el tipo tiene un destructor, porque el delete[]
necesitará desreferenciar ese puntero no inicializado. Por lo tanto, falla para std::string
pero no int
, porque int
es trivial y std::string
no.
Esto puede solucionarse utilizando una variable intermedia, de modo que la expresión no se pueda evaluar directamente a 0:
size_t length = 0;
std::string* p = new std::string[length];
// ...
delete[] p;