1

Je rencontre des difficultés faisant passer un grand tableau à une fonction en C.Passe grand tableau multidimensionnel pour fonctionner en C

Je déclare:

int image[height][width][3]={}; 

où la hauteur et la largeur peut être aussi grand comme 1500. Et quand je l'appelle:

foo((void *)image,height,width); 

qui est déclaré comme suit:

int *foo(const int *inputImage, int h, int w); 

Je reçois une erreur de segmentation. Ce qui est étrange est que si mes valeurs sont:

height=1200; 
width=290; 

Theres pas de problème, mais quand ils sont:

height=1200; 
width=291; 

i obtenir l'erreur mentionnée. A 4 octets par entier avec une hauteur et une largeur de 1500 (pire cas absolu), la taille du tableau serait de 27Mo, ce qui n'est pas très important et ne devrait pas vraiment importer car je ne fais que passer un pointeur vers le premier élément le tableau. Aucun conseil?

+2

Est-ce que 'image' est sur la pile? Si c'est le cas, vous manquerez probablement d'espace sur la pile. Essayez d'allouer dynamiquement le tableau. –

Répondre

3

À 27 Mo, votre baie est probablement plus grande que la pile, qui est généralement de 1 Mo. Vous corrompez votre processus dès que foo commence à travailler avec les données. Allouer le tableau sur le tas à la place:

typedef int (*image_buf)[height][width][3]; 
image_buf image = malloc(sizeof(image_buf)); 
... 
+0

Merci beaucoup, cela a fait l'affaire. Je vais en lire plus, car je ne vois toujours pas pourquoi passer un pointeur vers le premier élément déborde de la pile. – kirbuchi

+1

@kirbuchi: La pile est utilisée pour les variables locales. Vous débordez la pile non pas en passant le pointeur, mais plutôt en essayant de définir un tel tableau local. J'imagine que c'est tout simplement pas d'erreur jusqu'à ce que vous essayez d'accéder à un élément qui est passé votre espace de pile ... qui se produit dans votre fonction foo(). –

+1

J'ai fait quelques lectures et je pense que je comprends maintenant. L'espace de pile de sortie est utilisé pour les variables locales, donc lors de l'appel de foo(), il essaie d'allouer les 27 Mo sur la pile. – kirbuchi

0

vous pouvez vérifier la taille de la pile de processus par défaut avec ulimit -a 'sur les systèmes unix

(blocks, -c) 0 

données Taille de seg (koctets, -d) illimité priorité d'ordonnancement (-E) 20 de taille de fichier (blocs, -f) illimité signaux en attente (-i) 16382 mémoire verrouillée max (kilo-octets, -l) 64 taille de la mémoire max (kilo-octets, -m) illimité fichiers ouverts (-n) 1024 taille de tuyau (512 octets, -p) 8 des files de messages POSIX (les octets, -q) 819200 priorité en temps réel (-r) 0 taille de la pile (kilo-octets, -s) 8192 temps cpu (secondes, -t) illimité processus utilisateur maxi (-u) illimité mémoire virtuelle (kilo-octets) illimité verrous de fichier (-x) illimité

+0

Bien que cela soit vrai, passer une grande quantité de données en tant que tableau par valeur est horriblement mauvais pour la performance. Il est préférable d'allouer de la mémoire sur le tas et de passer un pointeur dessus, plutôt que d'augmenter la taille de la pile juste pour pouvoir copier 27 Mo de données sur la pile pour un argument de fonction ... –