2009-12-28 3 views
5

Je suis normalement en programmation en C++, mais j'utilise certaines fonctions de la bibliothèque pour mon caractère *. Certaines des pages de manuel comme 'getline', dit que l'entrée doit être un tableau malloced.Y at-il une différence entre les tableaux malloced et les tableaux nouveaux

Est-il acceptable d'utiliser 'new' à la place?

Je peux voir pour mon petit échantillon que cela fonctionne, mais cela pourrait-il à un certain moment entraîner un comportement étrange indéfini?

Je sais qu'un «nouveau» devrait correspondre à un «supprimer», et un «malloc» avec un «libre».

Je n'utilise pas non plus std :: string. Et c'est intentionnel.

Merci

+0

Non ce n'est pas OK. Mais si vous utilisez C++, pourquoi ne pas utiliser std :: getline()? –

+2

Chaque fois que vous voyez quelque chose comme ça dans la documentation, vous devez approfondir et déterminer s'ils recommandent un pointeur 'malloced' parce qu'ils utilisent la terminologie C ou parce que la fonction devrait appeler realloc() ou free(). Les réponses les mieux votées ci-dessous supposent le premier, bien que je pense que la fonction dont vous parlez a à voir avec ce dernier comme le souligne Martin. Il n'est pas correct d'associer incorrectement malloc/free et new/delete, il est donc préférable d'effectuer des recherches supplémentaires sur les fonctions spécifiques que vous appelez en cas de problème. –

Répondre

13

Le tampon passé à getline() DOIT être être validé.

La raison en est que getline() peut appeler realloc() sur le tampon si plus d'espace est requis.

realloc() comme free() ne doit être utilisé qu'avec la mémoire allouée par malloc().En effet, malloc() et de nouvelles allouer de la mémoire de différentes zones de stockage:

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

Fondamentalement nouvelles utilisations « Le « Free Store » tout en malloc utilise « Le Tas » Ces deux zones sont une partie de the "application Heap" (Bien que le standard ne nécessite pas de tas d'application car il s'agit d'un détail d'implémentation.) Bien qu'ils soient tous deux sur le "tas d'application", ces zones ne doivent pas se chevaucher.

La page de manuel pour getline():

Indication cette ligne:

En variante, avant d'appeler getline(), * lineptr peut contenir un pointeur vers un malloc() - tampon alloué * n octets . Si le tampon n'est pas assez grand pour contenir la ligne, getline() la redimensionne avec realloc(), mettant à jour * lineptr et * n si nécessaire.

+2

@Martin: vous pointez sur une fonction d'extension GCC "getline". Je ne pense pas que c'est trop génial de recommander l'utilisation de cette fonction non portable, en particulier pour les débutants –

+1

@Eli: la question mentionne spécifiquement 'getline'. –

+0

@Eli: Je recommanderais contre toutes les fonctions C où il existe une alternative C++ utilisable. Mais la question concerne spécifiquement la fonctionnalité C getline(). Et quand la documentation mentionne spécifiquement l'utilisation de la mémoire malloc (ed), il y a généralement une très bonne raison de le faire. –

2

Oui, il est correct d'utiliser un pointeur alloué avec new quand un « malloced » est attendue. Par ailleurs, getline n'est pas ISO C. Il y a une getline dans la bibliothèque C++ standard, mais on s'attend à std::string. Pour la lecture du fichier C standard, vous devez utiliser fgets. Les travaux suivants (code simplifié en supposant l'existence de infile et ne vérifie pas fgets valeur de retour - que vous devrait probablement dans le code réel):

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

Cependant, un avertissement obligatoire: il est préférable d'utiliser std::string et getline si vous utilisez C++.

+1

Je sais que la norme C originale est sortie de l'ANSI mais c'est un organisme national et ISO est maintenant responsable de la norme. S'il vous plaît essayez d'utiliser "ISO C" si vous le pouvez. – paxdiablo

+1

@paxdiablo: fixé à "ISO C". L'utilisation d'ANSI n'est qu'une habitude par le passé :-) –

+5

Il n'est pas toujours correct d'utiliser une nouvelle mémoire (ed) où malloc (ed) est attendu. Si elle utilise juste la mémoire comme mémoire brute bien. Mais si les routines de gestion de la mémoire sont utilisées sur les pointeurs, vous ne pouvez pas faire cette supposition. getline() peut potentiellement appeler realloc() sur le pointeur passé. Cela équivaut à appeler free() sur le pointeur, c'est-à-dire qu'il s'agit d'un comportement non défini. –

1

Il est parfaitement bien d'avoir un tableau 'new'ed' au lieu de 'malloc'ed array' dans ce but.

Les différences entre les deux sont (à la liste certains d'entre eux):

  • nouveau/supprimer appeler le constructeur/destructeur de l'objet associé à la différence malloc/libre. Ce dernier ne peut pas effectuer d'initialisation/désinitialisation.
  • nouveaux renvoie un pointeur de type correct mais le pointeur ce qui rend malloc doit être typecasted (C++)
  • nouveau/supprimer ne pas autre realloc contrairement à nouveau/supprimer

Ces choses ne vont pas faire beaucoup de différence dans votre programme; comme indiqué ci-dessus, il est tout à fait correct d'opter pour 'nouveau'

Votre code ne manquera pas, sauf si new ou malloc échoue, auquel cas 'new' déclenche une exception et malloc retourne un pointeur NULL.

EDIT: Aux fins, le tableau doit être « malloc. Je suppose que j'avais tort à l'époque! Merci Martin! :)

+0

@Srivatsan Iyer: Lisez ceci pour plus de différences: http://stackoverflow.com/questions/240212/what-is-the-difference-between-new-delete-and-malloc-free –

+0

Merci! En fait, j'ai juste essayé de mettre * quelques * des points; pas la plupart d'entre eux! : P – SuperSaiyan

+6

__FAIL__: Ceci est incorrect les lignes DOIVENT être mallocées. Voir ci-dessous. –