2017-10-01 5 views
-5

j'ai quelque chose de ce genre:Segmentation fault tout en utilisant malloc et la prise d'entrée

int n,m; 
scanf("%d %d",&m,&n); 
int *arr = malloc(sizeof(int)*n*m); 
for(int i=0;i<m*n;scanf("%d",arr+i),i++); 

maintenant pour dire n = 2 et m = 3, Il accepte les cinq premiers numéros, et donne une erreur de segmentation sur la sixième nombre. J'ai essayé d'imprimer des choses immédiatement après la boucle, mais ce n'est pas imprimé, aucune idée de ce que le problème pourrait être? J'ai utilisé de nombreuses constructions similaires et je n'ai jamais rencontré de problème auparavant. Le problème a été plus tard dans le programme, mais le fait est que j'ai eu un printf immédiatement après la boucle, et il n'a rien imprimé, donc j'ai supposé qu'il devait être ici. Pourquoi le printf n'a-t-il rien imprimé? Cela a-t-il quelque chose à voir avec l'exécution parallèle? Et désolé pour le mauvais format, je suis nouveau à empiler débordement.

+1

Lisez à propos (https [comportement non défini] (https://en.wikipedia.org/wiki/Undefined_behavior) et [débordement de tampon]: // fr .wikipedia.org/wiki/Buffer_overflow). Compilez avec toutes les informations d'avertissement et de débogage ('gcc -Wall -Wextra -g'). ** Utilisez le débogueur ** 'gdb' et [valgrind] (http://valgrind.org/).La prochaine fois que vous posez des questions sur SO, donnez quelques [MCVE] (http://stackoverflow.com/help/mcve). Cette question * corrige mon code * est hors sujet. Lire aussi [documentation] (http://fr.cppreference.com/w/c), notamment de 'malloc' et' scanf' –

+6

"quelque chose de ce genre" .... S'il vous plaît étudier le concept d'un [mcve] . – Yunnosch

+0

Vérifiez dans le débogueur les valeurs (avec un point d'arrêt sur la boucle 'for') de' m', 'n',' arr'. Je suis sûr que vous serez surpris. –

Répondre

1

Essayez ceci,

int n,m; 
printf("Enter two digits"); 
int scanCount = scanf("%d %d", &m, &n); 
if(scanCount < 2){ 
    perror("Input"); 
    exit(EXIT_FAILURE); 
} 
scanCount = 0; 
size_t size = sizeof(int) * n * m; 
int * arr = (int *) malloc(size); 
if (arr == NULL) { 
    perror("malloc"); 
    exit(EXIT_FAILURE); 
}; 
for(int i = 0; i < m * n; i++){ 
    if (scanf("%d", arr + i)) 
     scanCount++; 
} 
if(scanCount < m*n){ 
    perror("Input"); 
    exit(EXIT_FAILURE); 
} 
for(int i=0; i<n*m; i++){ 
    printf("\nValue at %d : %d\n", i, *(arr + i)); 
} 

J'ai modifié le programme donné ci-dessus un peu, et maintenant il fonctionne pour moi. La fonction malloc s'attend à ce que "std :: size_t size" (nous pouvons également fournir des valeurs entières) comme argument qui est la taille de la mémoire que nous devons allouer. S'il vous plaît visitez http://en.cppreference.com/w/cpp/memory/c/malloc pour toute référence.

Également nous devrions spécifier le type de la mémoire que nous créons (sinon cela pourrait produire une erreur dans certains compilateurs, comme ceci "conversion invalide de 'void *' à 'int *'"). Dans ce cas, nous sommes en train de créer un tableau d'entiers et nous pouvons utiliser le type cating, par exemple (int *) malloc (size).

Il est préférable de mettre en œuvre certains gestionnaires d'erreurs d'allocation de mémoire défaillante et entrées par scanf (vérifier les valeurs de retour de malloc et scanf)

+3

Echec de l'échec de 'malloc':' if (arr == NULL) {perror ("malloc"); exit (EXIT_FAILURE);}; 'et l'utilisation inutile de cast pour' malloc'; BTW 'scanf' peut également échouer et votre code ne vérifie pas cela. répondez ** pour l'améliorer –

+0

@BasileStarynkevitch Que dois-je vérifier en cas de scanf? – HariV

+0

En savoir plus sur [scanf] (http://fr.cppreference.com/w/c/io/fscanf) .Il retourne un élément comptez qui devrait être testé ... Parfois, '% n' est également utile –

1

J'ai essayé de lancer votre programme here. Pas d'erreur. Peut-être que c'était une coïncidence et juste arrivé à courir, mais peut-être vous avez eu une erreur lorsque vous avez imprimé les valeurs dans la boucle comme this?

Si c'est le cas, c'est parce que lors de la dernière itération, vous essayez d'écrire une partie de la mémoire qui n'a pas été allouée à malloc(). Comme arr[6] quand seulement jusqu'à arr[5] a été réellement alloué quand n = 2 et m = 3. Cela provoque un comportement indéfini. Regardez les liens @Basil souligné dans les commentaires.

Vous devez vérifier la valeur renvoyée par malloc() pour déterminer si l'allocation de mémoire a abouti. En cas d'échec, un NULL sera renvoyé.

Et la valeur de retour scanf() peut être vérifiée pour déterminer si elle a réussi ou non. Il renvoie le nombre d'affectations réussies qui, dans le cas du scanf() dans la boucle, doit être 1. Si ce n'est pas 1 une erreur s'est produite.

Ceci est une autre façon d'écrire cette boucle

for(i=0;i<m*n && scanf("%d", arr+i)==1;i++);