OVH Cloud OVH Cloud

déclaration tableau C99 taille variable

36 réponses
Avatar
Nicolas Aunai
salut,

je viens d'apprendre avec surprise que je peux faire :

int tab[x]; avec x une variable dont la valeur est acquise pendant
l'execution...


moi qui banissais totalement ce genre de chose, et hurlais après qqn
dès que je le voyais faire ça... je ne sais plus quoi penser...

pourquoi a-t-on permi ça en dans la norme C99 ?

si x est mal controlé dans mon programme, genre si a un moment j'ai
x=319391929919291929, ça me parait très dangereux


explications ?

--
Nico,
http://astrosurf.com/nicoastro
messenger : nicolas_aunai@hotmail.com

10 réponses

1 2 3 4
Avatar
Gabriel Dos Reis
writes:

| tout comme les malloc() sur unix avec "Out of Memory Killer"

Généraliser à partir d'un cas particulier est un métier à risques.

-- Gaby
Avatar
Gabriel Dos Reis
(Marc Espie) writes:

| In article <bpcngb$41i$,
| Marc Boyer wrote:
| >Marc Espie wrote:
| >> Ca permettra d'eviter l'abus de alloca(), fonction encore plus dangereuse,
| >> non standard, et qui nuit fortement a la sante.
| >
| > Mais alloca a quand même la gentillesse de signaler
| >son échec à ma connaissance.
|
| Ah oui, et quand l'echec c'est `il n'y a pas d'alloca sur ce systeme',

utilise un compilateur qui implémente alloca.

-- Gaby
Avatar
Gabriel Dos Reis
writes:

| > [inline] void* alloca(size_t s){ return malloc(s); }
|
| et un inline automatic_call void freea(s) { free(s) } ?

c'est plus ou moins ce que font certains compilateurs sur certaines
architectures.

Contrairement à la croyance populaire, les VLA ne sont pas obligés
d'être alloués sur la pile ; ils peuvent être implémenter en termes de
malloc/free.

-- Gaby
Avatar
Marc Boyer
Gabriel Dos Reis wrote:
Marc Boyer writes:

| Marc Espie wrote:
| > Ca permettra d'eviter l'abus de alloca(), fonction encore plus dangereuse,
| > non standard, et qui nuit fortement a la sante.
|
| Mais alloca a quand même la gentillesse de signaler
| son échec à ma connaissance.

Ah bon ? Tu as essayé ?


J'ai cru la doc ;-)
Disons que, quand je fais de C en ce moment, j'essaye
de faire du C99 pur.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(

Avatar
espie
In article ,
Gabriel Dos Reis wrote:
(Marc Espie) writes:

| Ah oui, et quand l'echec c'est `il n'y a pas d'alloca sur ce systeme',

utilise un compilateur qui implémente alloca.


Merci, j'ai deja suffisamment de dependances a des trucs qui sont
implementees par exactement un compilateur dans le code que je vois...

alloca n'est pas standard, et fout le bazard de maniere reguliere
dans du code parfaitement standard par ailleurs.

Il est effectivement souvent implemente de maniere naive sur la pile,
et, lorsque par exemple tu as affaire a une machine a taille de pile
limitee, ca fout un bordel noir. Par exemple, dans le temps, amigaos
ou macos jusqu'a 7 ou 8.

Et generalement, l'existence ou non d'alloca est plus liee a l'archi
qu'au compilateur. Ce qui fait vraiment raler, c'est que 9 cas sur 10
d'utilisation d'alloca ne sont pas necessaires du tout (malloc et free
auraient aussi bien marche) et que le cas restant aurait tres bien pu
etre evite en passant quelques minutes de plus sur le design... et
s'avere un peu delicat a eliminer dans le programme construit de
travers.

Avatar
kilobug

salut,


salut

je viens d'apprendre avec surprise que je peux faire :


int tab[x]; avec x une variable dont la valeur est acquise pendant
l'execution...


moi qui banissais totalement ce genre de chose, et hurlais après qqn
dès que je le voyais faire ça... je ne sais plus quoi penser...


j'évite aussi de l'utiliser, sauf cas particuliers

pourquoi a-t-on permi ça en dans la norme C99 ?


si x est mal controlé dans mon programme, genre si a un moment j'ai
x19391929919291929, ça me parait très dangereux


pas plus dangereux qu'un alloca (qui est non-portable) puisque ça
revient au même;et pas non plus beaucoup plus dangereux qu'un malloc.

malloc et alloca sont censés renvoyés NULL lorsque la mémoire n'est
pas disponible, mais sur la plupart des systèmes, il est
presqu'impossible au compilateur et même à l'OS de savoir s'il lui
reste de la mémoire.

De toute façon, un débordement de pile pourrait être fait avec une
fonction récursive tout aussi facilement:

int plop (int size)
{
char[size];
...
}

et

int sum (int n)
{
if (n <= 0
return 0;
return sum (n - 1) + n;
}

produisent le même effet avec un trop argument: stack oveflow, et mort
du programme.

<explication HS sur malloc et alloca>
La mémoire que retourne malloc ou alloca est en, effet de la mémoire
virtuelle, qui peut ne pas exister physiquement. La taille de la
mémoire virtuelle est limitée par l'OS et l'archi, mais est souvent
immense (3G sur Linux/ia32 par exemple).

La mémoire physique n'est allouée qu'au moment où un accès est fait à
la zone mémoire. À cause de méchanisme complexes (copy-on-write, ...),
la système peut allouer plus de mémoire virtuelle que ce qu'il a comme
mémoire physique (mémoire + swap + autre backsorage), et se retrouver
dans l'impossibilité d'accorder une page physique, même s'il avait
déjà accordé les pages virtuelles.

Tout ça pour dire: ne jamais faire confiance à malloc/alloca/.., même
s'ils disent "ok", une pénurie de mémoire peut toujours arriver, et
entrainer un OOM-kill ou équivalent.

</explication>

--
Gael Le Mignot "Kilobug" - - http://kilobug.free.fr
GSM : 06.71.47.18.22 (in France) ICQ UIN : 7299959
Fingerprint : 1F2C 9804 7505 79DF 95E6 7323 B66B F67B 7103 C5DA

Member of HurdFr: http://hurdfr.org - The GNU Hurd: http://hurd.gnu.org

Avatar
kilobug

Laurent Wacrenier wrote:
Marc Boyer écrit:
Ah... Je vois l'ampleur du problème...


Ça a tendance à faire une violation de segment, qui est
interuptible. Dans ce cas il vaut mieux quitter proprement. Un peu
comme quand malloc renvoie NULL.



Sauf que, un échec de malloc, à ma connaissance, il ne brise
pas le flot de controle du programme, et on peut donc avoir
assez facilement une idée de l'état du programme, et de
ce qu'il y a à faire pour quitter proprement, alors qu'avec
une interuption, c'est plus dur. Non ?


En téhorie oui, sauf que (voir mon post précédent), une pénurie de
mémoire peut se traduire par un OOM-kill (arrêt violent du programme)
ou une erreur de segmentation même avec malloc.

--
Gael Le Mignot "Kilobug" - - http://kilobug.free.fr
GSM : 06.71.47.18.22 (in France) ICQ UIN : 7299959
Fingerprint : 1F2C 9804 7505 79DF 95E6 7323 B66B F67B 7103 C5DA

Member of HurdFr: http://hurdfr.org - The GNU Hurd: http://hurd.gnu.org



Avatar
Marc Boyer
Gaël Le Mignot wrote:
La mémoire que retourne malloc ou alloca est en, effet de la mémoire
virtuelle, qui peut ne pas exister physiquement. La taille de la
mémoire virtuelle est limitée par l'OS et l'archi, mais est souvent
immense (3G sur Linux/ia32 par exemple).

La mémoire physique n'est allouée qu'au moment où un accès est fait à
la zone mémoire. À cause de méchanisme complexes (copy-on-write, ...),
la système peut allouer plus de mémoire virtuelle que ce qu'il a comme
mémoire physique (mémoire + swap + autre backsorage), et se retrouver
dans l'impossibilité d'accorder une page physique, même s'il avait
déjà accordé les pages virtuelles.


A ma connaissance, ce que tu décris, c'est *une* stratégie,
et je dirais même une stratégie puis privilégie la vitesse
au mépris de la fiabilité.
A ma connaissance, Solaris par exemple a eut cette
stratégie optimiste, puis et revenu en arrière.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(

Avatar
Marc Boyer
Gaël Le Mignot wrote:
En téhorie oui, sauf que (voir mon post précédent), une pénurie de
mémoire peut se traduire par un OOM-kill (arrêt violent du programme)
ou une erreur de segmentation même avec malloc.


Ce à quoi je serais tenté de répondre "mauvais OS, changer OS",
mais déjà qu'on choisit pas toujours son language, ni son
compilateur, on a parfois encore moins de choix pour l'OS.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(

Avatar
kilobug

Gaël Le Mignot wrote:
La mémoire que retourne malloc ou alloca est en, effet de la mémoire
virtuelle, qui peut ne pas exister physiquement. La taille de la
mémoire virtuelle est limitée par l'OS et l'archi, mais est souvent
immense (3G sur Linux/ia32 par exemple).

La mémoire physique n'est allouée qu'au moment où un accès est fait à
la zone mémoire. À cause de méchanisme complexes (copy-on-write, ...),
la système peut allouer plus de mémoire virtuelle que ce qu'il a comme
mémoire physique (mémoire + swap + autre backsorage), et se retrouver
dans l'impossibilité d'accorder une page physique, même s'il avait
déjà accordé les pages virtuelles.



A ma connaissance, ce que tu décris, c'est *une* stratégie,
et je dirais même une stratégie puis privilégie la vitesse
au mépris de la fiabilité.


En effet, mais si on veut programmer de manière portable, il faut
savoir qu'il existe des systèmes se comportant ainsi (pour le noyau
Linux que je connais bien, il se comporte ainsi par défaut, mais un
patch nommé "strict overcommit" corrgie le pb, au prix d'un peu de
performance)

--
Gael Le Mignot "Kilobug" - - http://kilobug.free.fr
GSM : 06.71.47.18.22 (in France) ICQ UIN : 7299959
Fingerprint : 1F2C 9804 7505 79DF 95E6 7323 B66B F67B 7103 C5DA

Member of HurdFr: http://hurdfr.org - The GNU Hurd: http://hurd.gnu.org


1 2 3 4