7
votes

Défaut de segmentation due au manque de mémoire en C

Ce code me donne la défaillance de la segmentation environ 1/2 du temps:

int main(int argc, char **argv) {
    float test[2619560];
    int i;
    for(i = 0; i < 2619560; i++)
        test[i] = 1.0f;
}


0 commentaires

4 Réponses :


24
votes

Vous débordez la taille de pile maximale par défaut, de 8 Mo.

Vous pouvez soit augmenter la taille de la pile - par exemple. Pour 32 Mo: p> xxx pré>

... ou vous pouvez passer à une allocation avec MALLOC code>: p>

float *test = malloc(2619560 * sizeof test[0]);


4 commentaires

Si vous utilisez MALLOC, vous êtes capable d'enregistrer le code si l'allocation réussisse - bien mieux que de traverser l'allocation et l'espoir qu'il ne se bloque pas. (addenda, pas tellement un commentaire @CAF)


@Sam Dufel Sachez que certains systèmes (par défaut par défaut) peuvent vous renvoyer un pointeur non nul de MALLOC, même si vous êtes hors de mémoire - conduisant à des accidents similaires lorsque vous essayez d'accéder à cette mémoire.


Il est probablement plus précis de dire que certains systèmes séparent les notions d'allocation de l'espace d'adresses virtuel et de commettre un magasin de soutien.


Selon la page Malloc Man, la norme UNIX98 nécessite MALLOC (), CALLOC () et RealLoc () pour définir Erno à Enomem lors de l'échec. Glibc suppose que cela se fait (et les versions Glibc de ces routines le font); Si vous utilisez une implémentation de MALLOC privée qui ne définit pas Erno, certaines routines de bibliothèque peuvent échouer sans avoir de raison dans Erno.



7
votes

En ce moment, vous allouez (ou au moins essayez de) 2619560 * Taille de (flotteur) octets sur la pile. Au moins dans la plupart des cas typiques, la pile ne peut utiliser qu'une quantité limitée de mémoire. Vous pouvez essayer de définir static à la place: xxx

ceci est sorti de la pile, de sorte qu'il peut généralement utiliser toute mémoire disponible. Dans d'autres fonctions, définir quelque chose comme statique modifie la sémantique, mais dans le cas de principal il fabrique peu de différence (autre que la possibilité la plus théorique d'un reconsive ).


2 commentaires

Récursive Main , hein? Ça a l'air intéressant.


@You: Parfois utilisé dans le golf de la COCCC ou du code. Sinon, pas tellement (et non autorisé en C ++).



0
votes

C'est la pile tropfleuse. Vous feriez mieux d'utiliser la fonction MALLOC pour obtenir la mémoire plus grande que la taille de la pile que vous pouvez l'obtenir de «ulimit -s».


0 commentaires

1
votes

Ne mettez pas un objet aussi grand sur la pile. Au lieu de cela, envisagez de le stocker dans le tas, par allocation avec Malloc () ou ses amis.

2,6 m floatts n'est pas si nombreux, et même sur un système 32 bits, vous devriez être correct pour l'espace d'adressage.

Si vous devez affecter un très grand tableau, assurez-vous d'utiliser un système 64 bits (en supposant que vous avez suffisamment de mémoire!). Les systèmes 32 bits ne peuvent aborder qu'environ 3G par processus, et même vous ne pouvez même pas l'attribuer tout comme un bloc contiguement unique.


0 commentaires