2009-12-28 14 views
5

Normalmente estoy programando en C++, pero estoy usando algunas funciones clibrary para mi char *. Algunas de las páginas de manual como 'getline' dicen que la entrada debe ser una matriz mal colocada.hay una diferencia entre las matrices malloced y las matrices nuevas

¿Está bien, usar 'nuevo' en su lugar?

Puedo ver por mi pequeña muestra que funciona, pero ¿podría esto en algún momento dar lugar a un extraño comportamiento indefinido?

Sé que un 'nuevo' debe coincidir con un 'eliminar' y un 'malloc' con un 'libre'.

Tampoco estoy usando std :: string. Y esto es intencional.

Gracias

+0

No, no está bien. Pero si usa C++, ¿por qué no usar std :: getline()? –

+2

Cada vez que vea algo como esto en la documentación, debe profundizar y determinar si recomiendan un puntero "mal orientado" porque utilizan la terminología C o porque se espera que la función llame a realloc() o libre(). Las respuestas más votadas a continuación suponen la primera, aunque creo que la función a la que se refiere tiene que ver con la última, como señala Martin. No está bien emparejar malloc/free y new/delete incorrectamente, por lo que es mejor realizar una investigación adicional sobre las funciones específicas a las que llama cuando esto ocurra. –

Respuesta

13

El búfer pasado a getline() DEBE ser malloced.

La razón es que getline() puede llamar a realloc() en el búfer si se requiere más espacio.

realloc() como free() solo se debe utilizar con la memoria asignada por malloc().Esto se debe a malloc() y nueva asignan memoria de diferentes áreas de almacenamiento:

Ver:. What is the difference between new/delete and malloc/free?

Básicamente nuevos usos "La 'tienda libre', mientras que malloc utiliza 'El Montón' Ambas áreas son parte de el "montón de aplicaciones" (aunque el estándar en realidad no requiere un montón de aplicaciones, ya que es un detalle de implementación). Aunque ambos están en el "montón de aplicaciones", estas áreas no se superponen. Si lo hacen, es un detalle de la implementación.

La página del manual para getline():

Aviso esta línea:

Alternativamente, antes de llamar a getline(), * lineptr puede contener un puntero a una malloc() - asignados búfer * n bytes de tamaño . Si el búfer no es lo suficientemente grande como para mantener la línea, getline() lo cambia de tamaño con realloc(), actualizando * lineptr y * n según sea necesario.

+2

@Martin: señala una función de extensión de GCC "getline". No creo que sea demasiado recomendable recomendar el uso de esta función no portátil, especialmente para los novatos –

+1

@Eli: la pregunta menciona específicamente 'getline'. –

+0

@Eli: recomendaría en contra de cualquier función C donde haya una alternativa C++ utilizable. Pero la pregunta es específicamente sobre la funcionalidad C getline(). Y cuando la documentación menciona específicamente el uso de la memoria malloc (ed), generalmente hay una muy buena razón para hacerlo. –

2

Sí, está bien usar un puntero asignado con new cuando se espera una "malloced".

Por cierto, getline no es ISO C. Hay una getline en la biblioteca estándar de C++, pero que uno espera un std::string. Para la lectura del archivo C estándar, debe usar fgets. Las siguientes obras (código simplificado suponiendo la existencia de infile y no comprueba fgets valor de retorno - que probablemente debería en código real):

// infile is some open FILE* object 
int mylen = 100; 
char* line = new char[mylen]; 
fgets(line, mylen, infile) 

Sin embargo, una advertencia obligatoria: es mucho mejor usar std::string y getline si estás usando C++.

+1

Sé que el estándar C original salió de ANSI pero es un organismo nacional e ISO ahora es responsable del estándar. Intenta usar "ISO C" si puedes. – paxdiablo

+1

@paxdiablo: fijado a "ISO C". usar ANSI es solo un hábito de tiempos pasados ​​:-) –

+5

No siempre es correcto usar memoria nueva (ed) donde se espera malloc (ed). Si solo usa la memoria como memoria sin procesar bien. Pero si las rutinas de administración de memoria se utilizan en los punteros, entonces no puede hacer esta suposición. getline() puede llamar a realloc() en el puntero pasado. Esto es equivalente a llamar a free() en el puntero, es decir, es un comportamiento indefinido. –

1

Está perfectamente bien tener una matriz 'nueva' en lugar de una matriz 'mallocada' para este propósito.

Las diferencias entre los dos son (a enumerar algunas de ellas):

  • nueva/borrar llamar al constructor/destructor del objeto asociado a diferencia de malloc/libre. Este último no puede realizar productos de inicialización/desinicialización.
  • nuevos devuelve un puntero del tipo adecuado, pero el puntero lo vuelve malloc tiene que ser typecasted (C++)
  • new/delete no tiene alternativa realloc a diferencia nuevo/Eliminar

Estas cosas no van a hacer mucha diferencia en su programa; tal como se indicó anteriormente, está perfectamente bien ir por 'nuevo'

Su código no fallará, a menos que falle el nuevo o malloc, en cuyo caso, 'nuevo' arroja una excepción y malloc devuelve un puntero NULL.

EDIT: Para el propósito, la matriz debe ser 'malloc'ed. ¡Creo que me equivoqué en ese momento! Gracias Martin! :)

+0

@Srivatsan Iyer: lea esto para conocer más diferencias: http://stackoverflow.com/questions/240212/what-is-the-difference-between-new-delete-and-malloc-free –

+0

¡Gracias! De hecho, solo traté de poner * algunos * puntos; ¡no la mayoría de ellos! : P – SuperSaiyan

+6

__FAIL__: Esto es incorrecto, las líneas DEBEN estar mal colocadas. Vea abajo. –

Cuestiones relacionadas