2009-08-13 8 views
1

J'ai essayé de réinventer la fonction strcpy C, mais lorsque je tente de l'exécuter je reçois cette erreur:Violation d'accès lors de l'utilisation de strcpy?

Unhandled exception at 0x00411506 in brainf%ck.exe: 0xC0000005: Access violation writing location 0x00415760. 

L'erreur se produit dans la ligne *dest = *src;. Voici le code:

char* strcpy(char* dest, const char* src) { 
    char* dest2 = dest; 
    while (*src) { 
     *dest = *src; 
     src++; 
     dest++; 
    } 
    *dest = '\0'; 
    return dest2; 
} 

EDIT: Wow, c'était rapide. Voici le code d'appel (strcpy est défini dans mystring.c):

#include "mystring.h" 
#include <stdio.h> 

int main() { 
    char* s = "hello"; 
    char* t = "abc"; 
    printf("%s", strcpy(s, t)); 
    getchar(); 
    return 0; 
} 
+3

Ce code serait utile. – Jason

+1

L'homme, c'était un tas de réponses rapides. Bienvenue dans le monde des tampons de dépassement. :) – Craig

+0

Comment l'appelez-vous? –

Répondre

15
char* s = "hello"; 
char* t = "abc"; 
printf("%s", strcpy(s, t)); 

Le compilateur a placé votre tampon de destination, s, dans la mémoire morte car il s'agit d'une constante.

char s[5]; 
char* t = "abc"; 
printf("%s", strcpy(s, t)); 

Vous devez résoudre ce problème. Cela alloue le tableau de destination sur la pile, qui est accessible en écriture.

+0

Merci. (15 caractères) – Javier

2

Qu'est-ce qui fait l'allocation pour dest avant qu'il ne soit passé dans votre strcpy? Les chances sont que c'est le problème.

+1

Non, ça n'a pas d'importance. C'est comme Michael l'a écrit. Le stuf était places dans des sections en lecture seule. Vous pouvez le changer dans gcc AFAIKT, mais je pense que changer cela est une très mauvaise idée. – Friedrich

7

Le problème potentiel évident est que votre mémoire tampon de sortie n'a pas assez de mémoire allouée ou que vous avez transmis la valeur NULL pour dest. (Probablement pas pour src ou il aurait échoué sur la ligne avant.)

S'il vous plaît donner un programme court mais complet pour reproduire le problème, et nous pouvons vérifier ...

Voici un exemple qui va bang pour moi sur Windows:

#include <stdlib.h> 

char* strcpy(char* dest, const char* src) { 
    char* dest2 = dest; 
    while (*src) { 
     *dest = *src; 
     src++; 
     dest++; 
    } 
    *dest = '\0'; 
    return dest2; 
} 

void main() { 
    char *d = malloc(3); 
    strcpy(d, "hello there this is a longish string"); 
} 

Notez que dans ce cas, je devais dépasser la mémoire allouée réelle d'un montant juste avant que je puisse provoquer le programme à mourir - juste « bonjour » ne tombe pas en panne, mais il a certainement pu en fonction de divers aspects du compilateur et de l'environnement d'exécution.

+1

Pourquoi au nom de toutes ces compilations renvoyez-vous dest2? Le code appelant ne se soucie pas d'une valeur de retour et le paramètre "entrée" "d" est laissé haut et sec. – Craig

+0

Je copiais juste le code de l'OP ... –

+0

Le texte d'exception indique qu'il s'agit d'une exception d'accès en écriture à une adresse proche de l'adresse de code - donc dest est un global ou une constante dans l'exécutable – Michael

0

Assurez-vous que dest a sa mémoire allouée avant d'appeler cette fonction.

0

Probablement un problème avec l'appelant: avez-vous vérifié le pointeur dest? Indique-t-il quelque chose de valable ou juste des ordures? De plus, le moins que vous puissiez faire est de vérifier les pointeurs NULL, comme si (! Dest ||! Source) {/ * faire quelque chose, comme retourner NULL ou lancer une exception * /} sur l'entrée de la fonction. Le code a l'air correct. Pas très sûr, mais ça va.

0

Il existe plusieurs erreurs.

  1. Vous n'allouez pas de tampon de retour pouvant contenir la chaîne copiée.
  2. Vous ne vérifiez pas si src est null avant d'utiliser * src
  3. Vous êtes tous les deux tring pour obtenir la réponse dans un paramètre et renvoyer la valeur. Fais l'un ou l'autre.
  4. Vous pouvez facilement dépasser le tampon de destination.

Bonne chance.

+0

Aucune de ces 'erreurs' n'est applicable au code OP. – hughdbrown

3

Votre strcpy() fonctionne correctement. Vous écrivez en mémoire en lecture seule. Voir cette description here.

Si vous aviez écrit cela, vous seriez bien:

#include "mystring.h" 
#include <stdio.h> 

int main() { 
    char s[] = "hello"; 
    char t[] = "abc"; 
    printf("%s", strcpy(s, t)); 
    getchar(); 
    return 0; 
} 
1

Il y a un problème avec l'appel de votre routine strcpy réinventé dans la routine principale, à la fois tableau de caractères: char * s = « bonjour "; char * t = "abc"; atterrira en mémoire LIRE SEULEMENT segment au moment de la compilation. Comme vous essayez d'écrire en mémoire pointée par s dans la routine strcpy, et comme il pointe vers un emplacement dans un segment READ ONLY, il sera intercepté et vous aurez une exception. Ces chaînes sont Lues SEULEMENT!

0

chaque fois que le code commence l'exécution (généralement il commence à partir de la fonction principale). Ici, le code signifie la séquence d'exécution. Aussi, lorsque le processus (séquence d'exécution) commence, le PCB (bloc de contrôle de processus) est créé, le pcb ayant une infromation complète sur le processus comme l'espace d'adressage, la pile kernal, ofdt .

dans votre code

char* s = "hello";
char* t = "abc";

c'est ce que vous avez les prises entrées de deux chaînes comme celui-ci.

ici, les chaînes (ce qui signifie double cité) qui sont présentes dans la section de texte de l'espace d'adressage du processus. ici la section de texte est celle de la section qui est présente dans l'espace d'adressage du processus et la section de texte ayant seulement les permissions de lecture seule. C'est pourquoi, lorsque vous essayez de modifier la chaîne source/la chaîne de destination, nous NE DEVONS PAS permettre de modifier les données présentes dans le texte. Donc, c'est ce que la raison de votre code, vous devez être PRUDENT. J'espère que tu as compris. Comment appelez-vous votre implémentation?

Questions connexes