Je m'attends à ce que l'extrait suivant affecte la mémoire pour cinq membres à l'aide de mais il semble allouer plus de cinq; C'est allouant six membres, pourquoi? p> calloc code>.
4 Réponses :
L'allocation de mémoire n'est pas comme acheter des sucettes. L'allocation de mémoire ressemble plus à l'achat de terres. P>
Si vous achetez cinq sucettes et que vous essayez de manger le sixième, cela ne fonctionne évidemment pas. Mais si vous achetez un terrain de dix pieds de cinquante pieds de terrain, vous commencez à mettre en place des bâtiments de 10x10 pieds et après la construction de cinq d'entre eux (occupant complètement votre terre), vous construisez un sixième enveloppant sur la terre de votre voisin, votre voisin pourrait ne pas remarquer tout de suite que vous pourriez vous en sortir. (Pendant un peu de temps, de toute façon. Il y a tenu d'être des problèmes à la fin.) P>
J'aime vraiment votre analogie de terre. Cela peut même être élargi pour dire que, lorsque vous construirez des limites, il se peut que vous détruisez votre garage de vos voisins qui se trouvent là-bas et il ne le découvrira pas avant d'essayer d'utiliser sa voiture (silencieux La corruption des données), ou votre propre travail se trompe horriblement parce que votre terre est située à une côte et que la "terre" que vous essayez de construire est en réalité ouvert océan (pas de mémoire présente, Segfault). Je dois absolument se rappeler que l'analogie!
Tout d'abord, obtenons quelque chose de clair: à toutes fins, c a Vous, comme le programmeur, vous devez vérifier que vous ne sortez pas des limites de la matrice et * (A + x) code> est identique à A [x] code>. p>.
calloc code> initialise tous les éléments avec 0. Pourquoi pensez-vous que vous avez 411? Essayez de le courir à nouveau, vous obtiendrez probablement une valeur différente. Cette mémoire que vous accédez à A [5] code> n'est pas attribuée pour le tableau. Au lieu de cela, vous sortez des limites de la matrice. Cette mémoire aurait pu être allouée très bien à autre chose. Si cela a été attribué à un autre programme, vous obtiendrez une erreur de segmentation lorsque vous exécutez le programme. P>
Point de confusion entier Pour moi, c'est quand un [5] me donne 0, j'aurais été satisfait si sa donne-moi quelque chose de Garbase (comme dans le cas d'un [6]) et cela reste la même chose à chaque fois que je l'exécute.
Redémarrez votre ordinateur et réessayez à nouveau, peut-être que les adresses de mémoire changent cette fois-ci. A [5] Code> Il se trouve juste à 0, c'est juste une coïncidence et n'a pas été défini comme ça par calloc code>
@Milan C'est l'un des aspects les plus déroutants du comportement non défini. Nous disons que cela fera quelque chose de hasard, nous disons que cela peut faire n'importe quoi i>, mais fréquemment, comme ici, cela fait quelque chose de complètement prévisible et presque raisonnable. Cela vous permet de rechercher la raison, cela peut vous demander si vous avez mal informé du code d'origine étant illégal ou ne fonctionne pas. Parfois, cependant, il n'y a pas d'explication décente pour le comportement apparemment prévisible, autrement que "un comportement non défini signifie n'importe quoi i> peut arriver, et cela inclut de faire quelque chose de raisonnable."
Le comportement non défini @milan signifie qu'il n'est pas garanti de fonctionner. Mais cela ne signifie pas que c'est garanti de ne pas travailler.
@Steve Summit Si vous souhaitez vous conformer à tout type de standard, vous ne devez pas avoir de comportement non défini dans votre code. C'est principalement parce que d'autres personnes peuvent essayer de compiler votre code avec un autre compilateur ou même une version différente du même compilateur et d'obtenir un résultat différent. Bien que parfois, vous pouvez vous en tirer, il est préférable de ne pas le faire à moins que vous ne cherchiez spécifiquement à ce genre de plaisir.
Eh bien, je ne suis pas vraiment sûr de cela, mais je n'ai essayé de fonctionner de deux configurations différentes et toujours les impressions A [5] 0. y a-t-il encore une raison logique?
@Milan tant que la norme ne le dit pas que vous ne pouvez pas compter dessus. Recherchez la documentation du compilateur, peut-être que c'est une extension ou quelque chose.
@Milan il y a probablement une raison logique à cela, mais (a) il ne peut être trouvé que en inspectant le code source de la version de votre machine de calloc code> et (b) ce n'est pas probablement très intéressant à la fin. Aussi (c) ce ne sera pas tout ce que vous pouvez utiliser, car il ne sera pas tout ce que vous pouvez dépendre de. Donc, alors que je comprends que votre curiosité est excitée ici (et la plupart du temps, la curiosité est une bonne chose), dans ce cas, je crains que vous soyez probablement déçu.
Il n'a pas alloué la mémoire plus que 5 code>. Il a alloué les membres 5 code> et les initialisés avec 0 code>. Lorsque vous accédez à l'extérieur de la mémoire allouée, cela peut être écrit quelque chose, et pas certainement une valeur non nulle. P>
Chaque fois qu'un MALLOC, CALLOC ou REALLOC est appelé, l'allocation de mémoire est effectuée à partir de la zone de tas.
Temps d'exécution / Allocation dynamique -> Haupe P>
Time statique / compilée-> pile p>
L'accès à des données en dehors des limites de votre objet est un comportement indéfini. Ne comptez pas dessus.
Il pourrait y avoir une taille minimale qu'il attribue. Mais vous êtes autorisé à accéder à des éléments 5 B> - ce que vous avez alloué. Si vous pensez que le sixième élément est à vous, votre code démontre aucune preuve i> de cela. Possible Que se passe-t-il si je définis une valeur en dehors de la mémoire allouée avec calloc? , Erreur hors limites , Quelle est la dangereuse d'accéder à un Array hors des limites? , confusion d'index MALLOC et réseau en C , etc.