2009-03-09 9 views
1

J'ai un ancien programme dans lequel une fonction de bibliothèque est utilisée et je n'ai pas cette bibliothèque. Donc, j'écris ce programme en utilisant des bibliothèques de C++. Dans cet ancien code, il y a une fonction qui est appelée comme ceciconvertir char ** en char * ou char

* string = newstrdup ("Some string goes here"); La variable de chaîne est déclarée comme char ** string

Ce qu'il peut faire dans cette fonction nommée "newstrdup"? J'ai essayé beaucoup de choses mais je ne sais pas ce qu'il fait ... Quelqu'un peut-il aider

+0

Pouvez-vous coller la fonction newstrdup()? –

+0

@tinkertim: "J'ai un ancien programme dans lequel une fonction de bibliothèque est utilisée et je n'ai pas cette bibliothèque" ... –

+0

Pouvez-vous coller un ancien code où newstrdup est utilisé? De préférence à l'intérieur d'une boucle. Avez-vous une déclaration pour newstrdup à partir d'un fichier .h? – jmucchiello

Répondre

3

il doit y avoir une raison pour laquelle ils ont écrit une "nouvelle" version de strdup. Il doit donc y avoir un boîtier d'angle qu'il gère différemment. comme peut-être une chaîne nulle renvoie une chaîne vide.

La réponse de litb est un remplacement pour strdup, mais je pense qu'il y a une raison pour laquelle ils ont fait ce qu'ils ont fait.

Si vous souhaitez utiliser strdup directement, utilisez une définition pour le renommer, plutôt que d'écrire du nouveau code.

+1

oui, puisqu'il est appelé "nouveau" strdup, je pense qu'il utilise opérateur new au lieu de malloc (strdup utilise malloc). ils peuvent également avoir leur propre pour des raisons de portabilité. Je ne sais pas :) –

+0

Il peut aussi s'appeler newstrdup() simplement parce que strdup() n'est pas standard, bien qu'il soit largement disponible, et ils voulaient rester clairs. L'utilisation de 'newstrdup()' pour indiquer 'strdup-variant-using-new' est également plausible. –

+0

La fonction intégrée strdup() est correcte. mais quand j'appelle la fonction en utilisant * response = newstrdup ("Some String") je reçois un défaut de segmentation. quelle peut être la raison de cela et comment surmonter? – Chaithra

0

newstrdup fait probablement une nouvelle chaîne qui est un double de la chaîne passée; il renvoie un pointeur sur la chaîne (qui est elle-même un pointeur vers les caractères).

+0

Bizarre, pourquoi ne retournerait-il pas simplement un pointeur sur les personnages? –

+0

@Iraimbilanja: il semble être. – sfossen

0

Il semble qu'il ait écrit une fonction strdup() pour fonctionner sur un pointeur existant, probablement pour le réaffecter à une nouvelle taille et ensuite remplir son contenu. Probablement, il le fait pour réutiliser le même pointeur dans une boucle où * chaîne va changer fréquemment tout en empêchant une fuite à chaque appel ultérieur à strdup().

Je l'implémenterais probablement comme string = redup (& chaîne, "nouveau contenu") .. mais c'est juste moi.

Modifier:

Voici un petit bout de ma fonction « RedPU » qui pourrait faire quelque chose de semblable à ce que vous avez publié, juste d'une manière différente:

int redup(char **s1, const char *s2) 
{ 
    size_t len, size; 

    if (s2 == NULL) 
     return -1; 

    len = strlen(s2); 
    size = len + 1; 

    *s1 = realloc(*s1, size); 

    if (*s1 == NULL) 
     return -1; 

    memset(*s1, 0, size); 
    memcpy(*s1, s2, len); 

    return len; 
} 

Bien sûr, je devrais probablement enregistrer une copie de * s1 et le restaurer si realloc() échoue, mais je n'ai pas besoin d'obtenir ce paranoïaque.

4

La fonction permet d'effectuer une copie des chaînes de caractères. Cela est souvent nécessaire pour obtenir une version en écriture d'un littéral de chaîne. Ils (littéraux de chaîne) ne sont pas inscriptibles, donc une telle fonction les copie dans un tampon accessible en écriture. Vous pouvez ensuite les passer à des fonctions qui modifient leur argument donné, comme strtok qui écrit dans la chaîne qu'il doit marquer.

Je pense que vous pouvez venir avec quelque chose comme ça, car il est appelé nouvelle strdup:

char * newstrdup(char const* str) { 
    char *c = new char[std::strlen(str) + 1]; 
    std::strcpy(c, str); 
    return c; 
} 

Vous seriez censé libérer une fois fait en utilisant la chaîne à l'aide

delete[] *string; 

Une autre façon d'écrire est d'utiliser malloc. Si la bibliothèque est vieux, il a peut-être utilisé que, qui C++ hérité de C:

char * newstrdup(char const* str) { 
    char *c = (char*) malloc(std::strlen(str) + 1); 
    if(c != NULL) { 
     std::strcpy(c, str); 
    } 
    return c; 
} 

Maintenant, vous êtes censé libérer la chaîne en utilisant free lorsque vous avez terminé:

free(*string); 

Préférez la première version si vous écrivez avec C++.Mais si le code existant utilise free pour libérer à nouveau la mémoire, utilisez la deuxième version. Méfiez-vous que la deuxième version renvoie NULL si aucune mémoire n'est disponible pour doubler la chaîne, tandis que la première renvoie une exception dans ce cas. Une autre note doit être prise au sujet du comportement lorsque vous transmettez un argument NULL à votre newstrdup. Selon votre bibliothèque qui peut être autorisée ou non autorisée. Insérez donc les vérifications appropriées dans les fonctions ci-dessus si nécessaire. Il existe une fonction appelée strdup disponible dans les systèmes POSIX, mais celle-ci n'autorise aucun argument NULL et n'utilise pas non plus l'opérateur C++ pour allouer de la mémoire.

Quoi qu'il en soit, j'ai regardé avec google codesearch pour newstrdup fonctions et trouvé un certain nombre. Peut-être que votre bibliothèque est parmi les résultats:

Google CodeSearch, newstrdup

+0

J'ai essayé votre programme comme ça. J'ai appelé newstrdup comme ceci. * ersponse = newstrdup (buffer) où buffer = "chaithra" mais en cours d'exécution il donne comme erreur de segmentation. – Chaithra

+0

Chaithra, avez-vous essayé les deux versions? –

+0

pas litb j'ai essayé seulement la première version. Maintenant, je vais essayer l'autre. – Chaithra

0

Je pense que vous avez besoin de regarder ce qui se passe avec la variable « chaîne » dans le code comme le prototype de la fonction newstrdup() semble être identique à la version de la bibliothèque strdup().

Y a-t-il des appels gratuits (* string) dans le code?

Il semblerait étrange de le faire, à moins qu'il ne conserve en interne une copie de la chaîne dupliquée et renvoie à nouveau un pointeur sur la même chaîne.

Encore une fois, je voudrais demander pourquoi?

+0

ya, je pensais la même chose, il doit y avoir un cas de coin qu'il gère différemment :) – sfossen

1

La ligne *string = newstrdup("Some string goes here"); ne montre aucune bizarrerie à newstrdup. Si string a le type char ** alors newstrdup renvoie simplement char * comme prévu. Vraisemblablement, string était déjà défini pour pointer vers une variable de type char * dans laquelle le résultat doit être placé. Sinon, le code écrit à travers un pointeur non initialisé.