IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Process terminated with status -1073741510 mais aucune erreur


Sujet :

C

  1. #1
    Invité
    Invité(e)
    Par défaut Process terminated with status -1073741510 mais aucune erreur
    Bonsoir tout le monde,

    Alors voilà j'ai un petit problème je n'arrive pas à me débarrasser de ceci "Process terminated with status -1073741510".
    C'est ce que m'affiche Code::Blocks après avoir exécuté mon programme.
    J'aimerais savoir d'où elle pourrait provenir (est-ce une erreur générale ?) et comment la corriger (j'ai cru comprendre que c'était un problème de mémoire mais je n'en suis pas sûr).

    Voici mon code (en espérant que cela ne vous décourage pas ) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
     
    #include "menu.h"
     
    link_s *init(SDL_Renderer *renderer)
    {
        int i;
        link_s *menu_elements = malloc(4 * sizeof(link_s));
        TTF_Font *links_normal_font = NULL;
        SDL_Color white = {255, 255, 255, 255};
     
        links_normal_font = TTF_OpenFont("data/Vanadine Regular.ttf", 50);
     
        menu_elements[0].name = "JOUEUR VS JOUEUR";
        menu_elements[1].name = "JOUEUR VS ORDI";
        menu_elements[2].name = "OPTIONS";
        menu_elements[3].name = "QUITTER";
     
        for(i = 0; i < 4; i++)
        {
            menu_elements[i].focus = 0;
            menu_elements[i].link_font = links_normal_font;
            menu_elements[i].link = TTF_RenderText_Blended(menu_elements[i].link_font, menu_elements[i].name, white);
            menu_elements[i].link_tex = SDL_CreateTextureFromSurface(renderer, menu_elements[i].link);
            SDL_QueryTexture(menu_elements[i].link_tex, NULL, NULL, &menu_elements[i].link_pos.w, &menu_elements[i].link_pos.h);
            menu_elements[i].link_pos.x = ((WINDOW_SIZE / 2) - (menu_elements[i].link_pos.w / 2));
            menu_elements[i].link_pos.y = ((225 + i * 90) - (menu_elements[i].link_pos.h / 2));
        }
     
        for(i = 0; i < 4; i++)
        {
            SDL_FreeSurface(menu_elements[i].link);
            SDL_DestroyTexture(menu_elements[i].link_tex);
        }
     
        TTF_CloseFont(links_normal_font);
     
        return menu_elements;
    }
     
    link_s *disp_menu(SDL_Renderer* renderer, link_s *menu_elements)
    {
        /* Fond */
        SDL_Rect background;
     
        SDL_Color white = {255, 255, 255, 255};
     
        /* Titre */
        TTF_Font *title_font = NULL;
        SDL_Surface* title = NULL;
        SDL_Texture* title_tex = NULL;
        SDL_Rect title_pos;
     
        /* Liens */
        int i;
        TTF_Font *links_normal_font = NULL;
        TTF_Font *links_hover_font = NULL;
        SDL_Color black = {0, 0, 0, 255};
     
        SDL_SetRenderDrawColor(renderer, 150, 150, 150, 255);
        background.x = 0;
        background.y = 0;
        background.w = WINDOW_SIZE;
        background.h = WINDOW_SIZE;
     
        title_font = TTF_OpenFont("data/GROBOLD.ttf", 65);
        title = TTF_RenderText_Blended(title_font, "Jeu de Dames", white);
        title_tex = SDL_CreateTextureFromSurface(renderer, title);
        SDL_QueryTexture(title_tex, NULL, NULL, &title_pos.w, &title_pos.h);
        title_pos.x = ((WINDOW_SIZE / 2) - (title_pos.w / 2));
        title_pos.y = ((WINDOW_SIZE / 6) - (title_pos.h / 2));
     
        links_normal_font = TTF_OpenFont("data/Vanadine Regular.ttf", 50);
        links_hover_font = TTF_OpenFont("data/Vanadine Bold.ttf", 55);
     
        for(i = 0; i < 4; i++)
        {
            if(menu_elements[i].focus == 0)
            {
                menu_elements[i].link_font = links_normal_font;
                menu_elements[i].link = TTF_RenderText_Blended(menu_elements[i].link_font, menu_elements[i].name, white);
                menu_elements[i].link_tex = SDL_CreateTextureFromSurface(renderer, menu_elements[i].link);
                SDL_QueryTexture(menu_elements[i].link_tex, NULL, NULL, &menu_elements[i].link_pos.w, &menu_elements[i].link_pos.h);
                menu_elements[i].link_pos.x = ((WINDOW_SIZE / 2) - (menu_elements[i].link_pos.w / 2));
                menu_elements[i].link_pos.y = ((225 + i * 90) - (menu_elements[i].link_pos.h / 2));
            }
            else
            {
                menu_elements[i].link_font = links_hover_font;
                menu_elements[i].link = TTF_RenderText_Blended(menu_elements[i].link_font, menu_elements[i].name, black);
                menu_elements[i].link_tex = SDL_CreateTextureFromSurface(renderer, menu_elements[i].link);
                SDL_QueryTexture(menu_elements[i].link_tex, NULL, NULL, &menu_elements[i].link_pos.w, &menu_elements[i].link_pos.h);
                menu_elements[i].link_pos.x = ((WINDOW_SIZE / 2) - (menu_elements[i].link_pos.w / 2));
                menu_elements[i].link_pos.y = ((225 + i * 90) - (menu_elements[i].link_pos.h / 2));
            }
        }
     
        SDL_RenderFillRect(renderer, &background);
     
        SDL_RenderCopy(renderer, title_tex, NULL, &title_pos);
     
        for(i = 0; i < 4; i++)
            SDL_RenderCopy(renderer, menu_elements[i].link_tex, NULL, &menu_elements[i].link_pos);
     
        SDL_RenderPresent(renderer);
     
        for(i = 0; i < 4; i++)
        {
            SDL_FreeSurface(menu_elements[i].link);
            SDL_DestroyTexture(menu_elements[i].link_tex);
        }
     
        TTF_CloseFont(links_hover_font);
        TTF_CloseFont(links_normal_font);
     
        SDL_DestroyTexture(title_tex);
        SDL_FreeSurface(title);
     
        TTF_CloseFont(title_font);
     
        return menu_elements;
    }
     
    int intersect(int a, int b, int x1, int y1, int x2, int y2)
    {
        if((a >= x1 && a <= x2) && (b >= y1 && b <= y2))
            return 1;
     
        return 0;
    }
     
    int have_focus(link_s *menu_elements, int x, int y)
    {
        int i;
     
        for(i = 0; i < 4; i++)
        {
            if(intersect(x, y, menu_elements[i].link_pos.x, menu_elements[i].link_pos.y, menu_elements[i].link_pos.x + menu_elements[i].link_pos.w, menu_elements[i].link_pos.y + menu_elements[i].link_pos.h))
            {
                menu_elements[i].focus = 1;
                return i;
            }
        }
     
        return -1;
    }
     
    int redirection(link_s *menu_elements, int link)
    {
        int done = 0;
     
        switch(link)
        {
            case 0:
                puts("1vs1");
                break;
     
            case 1:
                puts("1vsOrdi");
                break;
     
            case 2:
                puts("Options");
                break;
     
            case 3:
                puts("Quitter");
                clean(menu_elements);
                done = 1;
                break;
     
            default:
                puts("Erreur");
                break;
        }
     
        return done;
    }
     
    int manage_menu(SDL_Renderer* renderer, int x, int y, int click)
    {
        int i, focus_link, done = 0;
     
        link_s *menu_elements = init(renderer);
     
        if(!click)
        {
            focus_link = have_focus(menu_elements, x, y);
            for(i = 0; i < 4; i++)
            {
                if(i == focus_link)
                    menu_elements[i].focus = 1;
                else
                    menu_elements[i].focus = 0;
            }
        }
     
        menu_elements = disp_menu(renderer, menu_elements);
     
        if(click)
            done = redirection(menu_elements, have_focus(menu_elements, x, y));
     
        return done;
    }
     
    void clean(link_s *menu_elements)
    {
        free(menu_elements);
    }
    Merci d'avance,

    TcodingT

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Bonsoir,

    Quand on a des codes à rallonge et qui ne correspondent à rien, il faut avoir le réflexe de les convertir en hexadécimal. Sur 32 bits :

    -1073741510₁₀ = C000013A₁₆

    C0000 est un préfixe qui correspond au deux bits de poids fort mis à 1, et

    13A₁₆ = 314₁₀

    Une recherche avec le code hexadécimal nous envoie vers ceci : https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx
    « 0xC000013A: The application terminated as a result of a CTRL+C. »

    Si ce n'est pas toi qui a interrompu volontairement ton programme, alors c'est qu'il s'est auto-envoyé un signal ou quelque chose qui en tient lieu, ou encore qui a appelé quelque chose qui provoque le même phénomène, par exemple un abort().

    Il est probable que ce soit la bibliothèque que tu utilises qui ait volontairement mis fin au programme, elle-même parce que ton programme était incorrect (pointeur fou, corruption de pile ou de mémoire dus à un free() intempestif, etc.).

    Dans tous les cas, ton programme n'est pas complet : il nous manque au moins la fonction main et sans cela, impossible de trancher.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Merci pour cette réponse claire.
    Ce Ctrl + C pourrait donc être causé par la SDL ? Si oui auriez-vous une idée pour détecter ce qui à pu causer cette fin prématurée (je pense qu'il me manque des free mais je n'en suis pas sur).

    En tout cas voici mon main pour que vous puissiez y voir un peu plus clair (enfin j'espère ) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    #include "menu.h"
     
    int main(int argc, char* argv[])
    {
        SDL_Event event;
        int done = 0;
     
        if(TTF_Init() != 0)
        {
            printf("Echec de l'initialisation de TTF_Init: %s\n", TTF_GetError());
            return -1;
        }
     
        if(SDL_Init(SDL_INIT_VIDEO) != 0)
        {
            fprintf(stdout,"Echec de l'initialisation de la SDL: %s\n", SDL_GetError());
            return -1;
        }
     
        SDL_Window* pWindow = NULL;
        pWindow = SDL_CreateWindow("Test Menu pour les dames", SDL_WINDOWPOS_UNDEFINED,
                                                               SDL_WINDOWPOS_UNDEFINED,
                                                               WINDOW_SIZE,
                                                               WINDOW_SIZE,
                                                               SDL_WINDOW_SHOWN);
     
        if(pWindow)
        {
            SDL_Renderer *pRenderer = SDL_CreateRenderer(pWindow, -1, SDL_RENDERER_ACCELERATED);
            if(pRenderer)
            {
                while(!done)
                {
                    SDL_WaitEvent(&event);
                    switch(event.type)
                    {
                        case SDL_QUIT:
                            done = 1;
                            break;
                        case SDL_MOUSEMOTION:
                            done = manage_menu(pRenderer, event.motion.x, event.motion.y, 0);
                            break;
                         case SDL_MOUSEBUTTONDOWN:
                            done = manage_menu(pRenderer, event.button.x, event.button.y, 1);
                            break;
                    }
                }
                SDL_DestroyRenderer(pRenderer);
            }
            else
            {
                fprintf(stdout,"Echec de création du renderer (%s)\n", SDL_GetError());
            }
        }
        else
        {
                fprintf(stderr,"Echec de création de la fenêtre (%s)\n", SDL_GetError());
        }
     
        SDL_DestroyWindow(pWindow);
     
        TTF_Quit();
        SDL_Quit();
     
        return EXIT_SUCCESS;
    }
    Et mon menu.h au cas où :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    #ifndef MENU_H_INCLUDED
    #define MENU_H_INCLUDED
     
    #include <SDL2/SDL.h>
    #include <SDL2/SDL_image.h>
    #include <SDL2/SDL_ttf.h>
     
    #include <stdlib.h>
    #include <stdio.h>
     
    #define WINDOW_SIZE 600
     
    typedef struct link
    {
        char *name;
        char focus;
        SDL_Surface* link;
        SDL_Texture* link_tex;
        SDL_Rect link_pos;
        TTF_Font* link_font;
    }link_s;
     
    link_s *init(SDL_Renderer *renderer);
    link_s *disp_menu(SDL_Renderer* renderer, link_s *menu_elements);
    int intersect(int a, int b, int x1, int y1, int x2, int y2);
    int have_focus(link_s *menu_elements, int x, int y);
    int redirection(link_s *menu_elements, int link);
    int manage_menu(SDL_Renderer* renderer, int x, int y, int click); // click : booleen pour savoir si le bouton de la souris a ete appuye
    void clean(link_s *menu_elements);
     
    #endif // MENU_H_INCLUDED
    Merci d'avance et bonne soirée

    TcodingT

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Re-bonsoir,

    Compilé avec GCC sous Linux, j'obtiens :

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ ./programme
    Erreur de segmentation (core dumped)

    Donc, c'est bien une segfault. Un coup de débogueur :

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    $ gdb ./programme
    […]
    (gdb) run
    Starting program: /home/dom/tmp/cb/cb 
    […]
    Program received signal SIGSEGV, Segmentation fault.
    0x00007ffff78d73fc in TTF_SizeUTF8 () from /lib64/libSDL2_ttf-2.0.so.0
    Missing separate debuginfos, use: dnf debuginfo-install bzip2-libs-1.0.6-14.fc22.x86_64 dbus-libs-1.8.20-1.fc22.x86_64 freetype-2.5.5-2.fc22.x86_64 glibc-2.21-8.fc22.x86_64 libpng-1.6.19-1.fc22.x86_64 libX11-1.6.3-1.fc22.x86_64 libXcursor-1.1.14-4.fc22.x86_64 libXext-1.3.3-2.fc22.x86_64 libXi-1.7.4-2.fc22.x86_64 libXinerama-1.1.3-4.fc22.x86_64 libXrandr-1.4.2-2.fc22.x86_64 libXScrnSaver-1.2.2-8.fc22.x86_64 SDL2-2.0.3-5.fc22.x86_64 SDL2_ttf-2.0.12-4.fc22.x86_64 zlib-1.2.8-7.fc22.x86_64
    (gdb) bt
    #0  0x00007ffff78d73fc in TTF_SizeUTF8 () from /lib64/libSDL2_ttf-2.0.so.0
    #1  0x00007ffff78d8505 in TTF_RenderUTF8_Blended () from /lib64/libSDL2_ttf-2.0.so.0
    #2  0x00007ffff78d890c in TTF_RenderText_Blended () from /lib64/libSDL2_ttf-2.0.so.0
    #3  0x000000000040103b in init (renderer=0x6940c0) at fonc.c:21
    #4  0x0000000000401b9e in manage_menu (renderer=0x6940c0, x=192, y=311, click=0) at fonc.c:182
    #5  0x0000000000401d9c in main (argc=1, argv=0x7fffffffde68) at cb.c:41

    Ligne 182 dans managemenu(), on lit :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
        link_s *menu_elements = init(renderer);

    Et ligne 21 dans init(), on trouve :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include "menu.h"
    
    link_s *init(SDL_Renderer *renderer)
    {
        int i;
        link_s *menu_elements = malloc(4 * sizeof(link_s));
        TTF_Font *links_normal_font = NULL;
        SDL_Color white = {255, 255, 255, 255};
    
        links_normal_font = TTF_OpenFont("data/Vanadine Regular.ttf", 50);
    
        menu_elements[0].name = "JOUEUR VS JOUEUR";
        menu_elements[1].name = "JOUEUR VS ORDI";
        menu_elements[2].name = "OPTIONS";
        menu_elements[3].name = "QUITTER";
    
        for(i = 0; i < 4; i++)
        {
            menu_elements[i].focus = 0;
            menu_elements[i].link_font = links_normal_font;
            menu_elements[i].link = TTF_RenderText_Blended(menu_elements[i].link_font, menu_elements[i].name, white);

    Donc, un plantage à l'intérieur de la bibliothèque (rattrapée par elle-même ou par ce qui la contient), dû à un pointeur NULL (erreur très fréquente en C), lui-même dû au fait que tu as ouvert une fonte sans vérifier si l'opération avait réussi (erreur EXTRÊMEMENT fréquente en SDL, principalement avec l'ouverture de fonte, ne serait-ce que parce que la fonte n'est pas disponible sur toutes les plateformes et parce que si elle l'est, ce n'est pas forcément au même endroit).

    Donc, ça plante chez moi à cause des fontes mais il est possible que l'opération se passe bien chez toi si le fichier est à sa place et que ton programme plante à un autre endroit. Il faut utiliser un débogueur pour le savoir.

  5. #5
    Invité
    Invité(e)
    Par défaut
    En effet, le programme ne plante pas chez moi (il marche même ! ). C'est vrai que je n'avais pas pensé à l'histoire des fonts et je rajouterais par la suite les vérifications appropriées.
    Néanmoins, le débugger de Code::Blocks n'est pas ce que je maîtrise le mieux et lorsque je lance un débuggage avec ce dernier il ne me retourne aucune erreur (2 warnings comme quoi argc et argv ne sont pas utilisés) et me met :
    Process terminated with status 0
    J'avoue que là j'y comprend plus grand chose ^^ (est-ce que mon débugger pourrait-être mal configuré ?).
    Une dernière question au passage à quoi correspond exactement Process terminated with status XX (sa différence avec le retour du programme par exemple).

    Merci d'avance et bonne journée.

    TcodingT

  6. #6
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Ce n'est pas le débugger qui génère les warnings mais le compilateur (je ne connais pas Code::Blocks mais j'imagine que ça utilise MinGW).

    Quant à Process terminated with status 0, c'est le code de retour de ta fonction d'entrée main et probablement la valeur d'EXIT_SUCCESS sur ton système. La session d'exécution s'est donc terminée normalement ce qui correspond à tes dires.

    Pour rejoindre Obsidian, vérifies toujours la validité des résultats que tu obtiens de la part de fonctions tierces, même à l'aide d'un simple assert :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int ret = load_font("myfont.ttf");
    assert(ret == 0 && "could not load font");
    Plus tôt elles seront interceptées, plus tôt tu identifieras l'origine de tes erreurs et tu t'épargneras bien des galères.

  7. #7
    Invité
    Invité(e)
    Par défaut
    Tout d'abord oui Code::Blocks utilise bien MinGW (en tout cas le mien ^^).
    Effectivement je n'ai mis aucune validation dans mon code car à la base cela devait être un quelconque petit test.

    Ensuite, cette réponse m'amène donc à une nouvelle question puisque mon programme me retourne 0 mais Code::Blocks me retourne toujours -1073741510 en mode release je ne comprend donc pas trop.
    Et enfin, je ne connais pas la fonction assert, j'ai l'habitude de faire un bête if comparatn la valeur de retour de la foction (est-ce mieux un assert ?)

    Merci d'avance et bonne soirée à tous.

    TcodingT

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par TcodingT Voir le message
    Ensuite, cette réponse m'amène donc à une nouvelle question puisque mon programme me retourne 0 mais Code::Blocks me retourne toujours -1073741510 en mode release je ne comprend donc pas trop.
    On lit sur certains forums que cela arrive quand c'est l'antivirus de la machine qui intercepte volontairement le processus contrevenant. Le désactiver permet parfois de permettre à ce processus d'aller jusqu'à son terme mais s'il se fait intercepter, c'est de toute façons parce qu'il fait quelque chose de mal. Code::Blocks doit mettre en place le même genre de périmètre pour superviser ses propres productions et y mettre fin quand quelque chose ne tourne pas rond.

    À part cela, sous UNIX (et sous de nombreux systèmes depuis les années 60 jusqu'aux BASIC des années 80), Ctrl+C est la commande qui sert à interrompre volontairement un processus et concrètement, cela va provoquer l'envoi du signal SIGINT. Or, il se trouve que ce que l'on pensait être des signaux UNIX uniquement sont en fait également définis par la norme C dans la section 7.14, au moins en ce qui concerne les plus courants (SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV et SIGTERM). Ce qui veut dire que même si Windows ne s'appuie pas nativement sur ces mécanismes pour sa propre programmation système, il reste obligé d'honorer les conditions de la norme C, au moins en ce qui concerne abort(). Tout cela pour dire que si tu reçois ce code, c'est probablement parce que quelque chose a envoyé l'équivalent d'un SIGINT à ton programme.

    Et enfin, je ne connais pas la fonction assert, j'ai l'habitude de faire un bête if comparatn la valeur de retour de la foction (est-ce mieux un assert ?)
    « assert() » sert à exprimer une assertion à un endroit donné de ton programme, c'est-à-dire à énoncer un fait censé être vrai à ce stade. Concrètement, la fonction va évaluer l'expression passée entre parenthèses et la convertir en booléen si elle ne l'est pas déjà. Si l'expression est vraie (vaut true), le programme se poursuit normalement. Si elle est fausse, la fonction appelle abort(), qui met fin au programme en envoyant SIGABRT (et en quittant le processus elle-même et de toutes façons si jamais le signal est intercepté).

    D'autre part, si la macro NDEBUG est définie à la compilation, alors cette instruction est purement et simplement ignorée et n'apparaîtra jamais dans l'exécutable final quelque soit sa forme, évitant tout effet de bord. À utiliser en dernière phase de test et avant de livrer le produit.

    Mais pour l'heure, un petit coup de valgrind s'impose (je suis allé chercher tes fontes pour remettre ton programme en conditions normales) :

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    $ valgrind ./programme
    
    […]
    
    ==17191== HEAP SUMMARY:
    ==17191==     in use at exit: 66,612 bytes in 573 blocks
    ==17191==   total heap usage: 80,608 allocs, 80,035 frees, 360,361,026 bytes allocated
    ==17191== 
    ==17191== LEAK SUMMARY:
    ==17191==    definitely lost: 21,406 bytes in 103 blocks
    ==17191==    indirectly lost: 1,792 bytes in 8 blocks
    ==17191==      possibly lost: 0 bytes in 0 blocks
    ==17191==    still reachable: 43,414 bytes in 462 blocks
    ==17191==         suppressed: 0 bytes in 0 blocks
    ==17191== Rerun with --leak-check=full to see details of leaked memory
    ==17191== 
    ==17191== For counts of detected and suppressed errors, rerun with: -v
    ==17191== Use --track-origins=yes to see where uninitialised values come from
    ==17191== ERROR SUMMARY: 12 errors from 9 contexts (suppressed: 0 from 0)

    Donc pas mal de fuites de mémoire en tous genres à régler. Malheureusement, il arrive fréquemment que les bibliothèques elles-mêmes soient sujettes à de telles fuites (y compris les bibliothèques système), si bien qu'en conditions de travail, il est souvent nécessaire (mais délicat) d'établir une liste d'exceptions.

    On trouve déjà quelques détails qui peuvent faire tiquer :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        if(TTF_Init() != 0)
        {
            printf("Echec de l'initialisation de TTF_Init: %s\n", TTF_GetError());
            return -1;
        }
     
        if(SDL_Init(SDL_INIT_VIDEO) != 0)
        {
            fprintf(stdout,"Echec de l'initialisation de la SDL: %s\n", SDL_GetError());
            return -1;
        }

    Es-tu sûr qu'il faille initialiser TTF_Init avant SDL_Init ?

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    typedef struct link
    {
        char *name;
        char focus;
        SDL_Surface* link;
        SDL_Texture* link_tex;
        SDL_Rect link_pos;
        TTF_Font* link_font;
    }link_s;
     
        menu_elements[0].name = "JOUEUR VS JOUEUR";
        menu_elements[1].name = "JOUEUR VS ORDI";
        menu_elements[2].name = "OPTIONS";
        menu_elements[3].name = "QUITTER";

    Tu associes des chaînes constantes à des pointeurs vers des caractères variables.

  9. #9
    Invité
    Invité(e)
    Par défaut
    D'abord merci d'avoir pris le temps de me donner des réponses aussi claire !

    J'avoue que le coup de l'initialisation de TTF avant la SDL c'est pas mal dans son genre et je l'ai pas vu venir ^^.

    Pour revenir à assert est-ce que cela présente un réel avantage sur les if (dans ces cas de vérifications je parle) ? J'ai rapidement parcouru le man passé en lien sur ce sujet et je me demande également, cette macro NDEBUG c'est donc le programmeur qui doit lui même la définir ?

    D'autre part pour les chaînes de caractère, je devrais donc remplacer par quelque chose comme : ?

    Une autre question qui me traverse l'esprit à propos de ces listes d'exceptions dont vous parlez, qu'est-ce qu'elles représentent concrétement et comment pourrait-on les mettre en place ?
    Et le fait d'associer
    des chaînes constantes à des pointeurs vers des caractères variables
    peut-il engendrer des fuites de mémoires ? Si oui comment ?

    P.S : Désolé si je pose trop de questions et de manière un peu éparpillé mais bon je débute et je trouve vos explications claires et concises donc j'en profite . Tout est bon à prendre quand on débute.

    Merci encore et bonne soirée.

    TcodingT

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par TcodingT Voir le message
    D'abord merci d'avoir pris le temps de me donner des réponses aussi claire !

    J'avoue que le coup de l'initialisation de TTF avant la SDL c'est pas mal dans son genre et je l'ai pas vu venir ^^.
    C'est-à-dire que je ne suis même pas encore sûr que ce soit un mal ou un bien. Je suis allé parcourir un peu la doc de la SDL pour savoir comment se comporter avec les initialisations partielles et je n'ai pas encore réussi à trancher…

    Pour revenir à assert est-ce que cela présente un réel avantage sur les if (dans ces cas de vérifications je parle) ? J'ai rapidement parcouru le man passé en lien sur ce sujet et je me demande également,
    Ce n'est pas la même chose. Un « if » ordinaire va être une mesure nécessaire et permanente. Par exemple, il est obligatoire (en principe) de vérifier à chaque fois la valeur de retour d'un malloc() parce que la fonction peut échouer. Et quand c'est le cas, on souhaite absolument prendre le cas en main et agir en conséquence. On ne souhaite surtout pas mettre fin brutalement au programme.

    « assert() », en revanche, est faite pour être placée à des points clés de ton programme et n'être utilisée qu'au stade expérimental de ton application ou en phase de déboguage. Elle sert explicitement à dire que normalement, à un certain stade, une condition donnée doit toujours être vraie. Si ce n'est pas le cas, c'est qu'il y a quelque chose d'incorrect dans le programme même si cela n'engendre pas forcément de plantage. Ça permet de détecter les erreurs ou les cas de figure inenvisagés pendant le développement. En cas d'arrêt, la fonction renvoie également un message d'erreur à l'écran avec le nom du fichier source et la ligne concernée. Comme indiqué dans la man page, ce sont des informations utiles pour le développeur mais complètement inutiles à l'utilisateur.

    C'est utile également parce qu'on peut se permettre de les placer un peu partout où l'on souhaite mettre un « checkpoint » sans se soucier d'avoir à faire le ménage ensuite, puisque la macro ci-après sert justement à les faire disparaître en conditions de production. Il arrive qu'on les oublie et qu'elles perdurent dans l'exécutable définitif. Ce n'est pas forcément une mauvaise chose puisque si une condition n'est pas souhaitable en phase de test, elle ne l'est généralement pas plus en production.

    cette macro NDEBUG c'est donc le programmeur qui doit lui même la définir ?
    Oui, mais elle peut consister en un simple #define NDEBUG mais également et surtout en un flag passé au compilateur. Avec GCC, on ajoute « -DNDEBUG » sur la ligne de commandes. Ces flags sont généralement définis par le Makefile et passés au compilateur à toutes les étapes. Il y a des chances que Code::Blocks gère cette macro s'il propose des modes Debug et Release.

    D'autre part pour les chaînes de caractère, je devrais donc remplacer par quelque chose comme : ?
    Pas forcément. Si tes chaînes n'ont jamais vocation à être modifiées, ça ne sert à rien de réserver de la mémoire pour elles. Par contre, il faut déclarer tes pointeurs en tant que char const * ou const char *.

    Une autre question qui me traverse l'esprit à propos de ces listes d'exceptions dont vous parlez, qu'est-ce qu'elles représentent concrétement et comment pourrait-on les mettre en place ?
    Et le fait d'associer peut-il engendrer des fuites de mémoires ? Si oui comment ?
    Je parlais d'exceptions au sens large, et dans l'acception première du terme. Le terme officiel a l'air d'être « suppression ». Voir ici : http://valgrind.org/docs/manual/manu...-core.suppress
    Mais tu n'en es pas encore là.

    Bon courage.

  11. #11
    Invité
    Invité(e)
    Par défaut
    Encore une fois merci pour toutes ces réponses !

    Tout d'abord pour l'initialisation de TTF, j'ai fait quelque recherche et j'ai trouvé ceci
    SDL does not have to be initialized before this call.
    this call
    correspond à TTF_Init() (c.f https://www.libsdl.org/projects/SDL_...ttf_frame.html).
    Néanmoins dans la F.A.Q SDL de Developpez on peut lire que :
    Il faut tout d'abord initialiser SDL_ttf (après SDL bien sûr)
    . Donc ceci peut amener à penser que initialiser SDL_TTF avant la SDL elle-même relève surtout de la bonne pratique (et cela paraît aussi plus logique quand on y réfléchit étant donner que TTF utilise des SDLSurface il me semble^^).

    Ensuite, pour les const devant les char, ils servent juste à montrer que la variable ne pourra pas être modifié c'est ca ?

    Et de toute façon même en faisant cela, j'ai toujours ce problème de retour .

    (J'ai aussi découvert un autre bug mais celui-ci je sais d'où il vient )

    Merci d'avance et bonne journée.

    TcodingT

  12. #12
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par TcodingT Voir le message
    Ensuite, pour les const devant les char, ils servent juste à montrer que la variable ne pourra pas être modifié c'est ca ?
    La variable (le pointeur lui-même), si ! Mais pas ce qu'il pointe.

  13. #13
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Oui, mais elle peut consister en un simple #define NDEBUG mais également et surtout en un flag passé au compilateur. Avec GCC, on ajoute « -DNDEBUG » sur la ligne de commandes. Ces flags sont généralement définis par le Makefile et passés au compilateur à toutes les étapes. Il y a des chances que Code::Blocks gère cette macro s'il propose des modes Debug et Release.
    Remarque : nombreux sont les compilateurs qui positionnent ou pas cette macro en fonction du niveau d'optimisations. En -O0, les assertions seront actives ; en -O3, elles ne le seront pas. Ça peut-être un peu "piégeux"...

  14. #14
    Invité
    Invité(e)
    Par défaut
    La variable (le pointeur lui-même), si ! Mais pas ce qu'il pointe.
    Mais du coup qu'elle est l'intérêt ? Et en tout les cas, est-ce que cela peux poser un problème de mémoire ?

    en fonction du niveau d'optimisations
    Je suis désolé mais je ne sais pas à quoi correspond les niveaux d'optimisation (juste déjà vu quelque chose comme ça il me semble dans les options de debugger il me semble)

    TcodingT

  15. #15
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par TcodingT Voir le message
    Mais du coup qu'elle est l'intérêt ? Et en tout les cas, est-ce que cela peux poser un problème de mémoire ?
    Tu ne peux pas modifier le contenu de la chaîne pointée, i.e. remplacer "abcd" par "toto". En revanche le pointeur vers la chaîne peut être modifié pour pointer vers un autre tampon (constant) de char.


    Citation Envoyé par TcodingT Voir le message
    Je suis désolé mais je ne sais pas à quoi correspond les niveaux d'optimisation (juste déjà vu quelque chose comme ça il me semble dans les options de debugger il me semble)
    Ton compilateur est un outil très puissant qui est capable d'optimiser ton code pour la vitesse d'exécution et/ou la taille du code machine. Cela est optionnel et s'active manuellement. Tu n'as probablement pas besoin de t'en préoccuper pour l'instant, cela intervient plus tard dans la phase de développement.


    Pour placer un mot au sujet d'assert (et paraphraser Obsidian), il peut être utilisé pour remplacer la gestion d'erreur dans la phase de développement (et dans cette phase uniquement, parce qu'un programme qui abort au premier fichier non présent ce n'est pas très classe ). C'est effectivement équivalent à if (!ok) abort();. En programmation et en C plus qu'ailleurs mieux vaut tout arrêter dès que ça foire, il peut vraiment se passer n'importe quoi si tu laisses l'erreur faire boule de neige..
    On peut aussi s'en servir pour s'assurer que les préconditions aux appels de fonction sont remplies, c'est mieux qu'un commentaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include <assert.h>
     
    double my_sqrt(double x) { // racine carrée
        assert(x >= 0 && "square root of a negative number is undefined");
     
        // ...
    }

  16. #16
    Invité
    Invité(e)
    Par défaut
    En revanche le pointeur vers la chaîne peut être modifié pour pointer vers un autre tampon (constant) de char.
    Dans mon cas j'avoue que je ne voie pas l'intérêt puisque chaque lien à un nom attitré ?

    Ton compilateur est un outil très puissant qui est capable d'optimiser ton code pour la vitesse d'exécution et/ou la taille du code machine. Cela est optionnel et s'active manuellement.
    Par curiosité plus que pour l'utiliser maintenant comment ça marche en gros ?

    Et merci pour ces compléments sur l'assert ! ^^

    Bonne après-midi.

    TcodingT

  17. #17
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par TcodingT Voir le message
    Dans mon cas j'avoue que je ne voie pas l'intérêt puisque chaque lien à un nom attitré ?
    Il faut considérer les choses sous deux angles :

    Premièrement, n'importe quelle donnée peut être qualifiée de constante avec const. Par exemple int const a = 5; déclare un entier constant. Il aura toutes les caractéristiques d'un entier variable ordinaire : il existera en mémoire, aura une adresse fixe qui pourra être obtenue avec « & », etc. La seule différence est qu'il sera interdit au programme C d'écrire dedans et que le compilateur refusera de produire du code lui demandant de le faire. On fixe donc sa valeur à l'initialisation. Un pointeur suit exactement les mêmes règles et peut donc être variable ou constant, lui aussi. La seule différence est qu'il pointe des données qui — elles-mêmes — peuvent être variables ou constante, et qui donc ont besoin d'être qualifiées de la sorte dans la déclaration du pointeur.

    Il est très utile d'avoir un pointeur variable sur des données constantes quand ces données sont une chaîne, généralement une chaîne de caractères, et qu'il faut incrémenter le pointeur pour lire le caractère suivant, fût-il constant. Par contre, ce n'est pas forcément nécessaire : il est possible d'indexer le pointeur comme un tableau avec « [ ] » ou d'utiliser l'arithmétique des pointeurs, pour accéder à un élément n par rapport à la valeur du pointeur, qui sert de base.

    Ensuite, si tu définis des données dans ton programme, disons là encore une chaîne de caractères, alors cette chaîne va devoir prendre place dans le fichier exécutable de ton programme qui, elle, une fois chargée en mémoire, ne peut être modifiée. En outre, il n'existe pas de type natif « chaîne de caractères » à proprement parler en langage C : lorsque tu écris une chaîne entre guillemets, le contenu de celle-ci est intégré au code en langage machine et au niveau syntaxique, la chaîne entre guillemets est interprétée comme une expression évaluable, et cette valeur est un pointeur vers les données en mémoire (au sein du code) pour que l'on puisse les lire. Cette expression est donc naturellement un pointeur constant vers des caractères constants.

    Quand tu déclares un tableau (variable) de caractères et que tu initialises son contenu avec une chaîne entre guillemets, le processus est similaire : comme la mémoire est allouée à l'exécution (dans la pile), il faut bien recopier la chaîne issue de l'image de l'exécutable vers la zone où se trouve le pointeur, surtout si le tableau en question peut être détruit et réalloué plusieurs fois au cours de l'exécution (cas d'un tableau local au sein d'une fonction). Ce sont les bibliothèques standard du C qui font cela pour toi de façon transparente, mais elles le font.

    Pour finir un exemple. Voici une fonction qui renvoie le nom du jour de la semaine (« lundi » à « dimanche » en fonction de la date du mois (du 1er au 31). Cette fonction ne fonctionne que pour les mois qui commencent un lundi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #include <stdio.h>
     
    char const * jourdelasemaine (int j)
    {
        char const * const tableau[] = { "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche" }
        char const * jour;
     
        jour = tableau[(j-1)%7];
        printf ("Nous sommes %s\n",jour);
     
        return jour;
    }
     
    int main (void)
    {
        jourdelasemaine (3);
        return 0;
    }
    Dans cet exemple, je déclare volontairement un pointeur variable « jour » dont j'aurais pu me passer en temps normal, mais il sert à illustrer mes propos : je crée un tableau de sept pointeurs vers des chaînes constantes (les jours de la semaine). Ces pointeurs sont eux-mêmes constants, ce qui fait que je ne pourrai pas changer les jours de la semaine à l'intérieur de mon tableau, ni leur ordre.

    J'affecte ensuite à « jour » l'adresse en mémoire de la chaîne correspondant au jour adéquat. Les caractères eux-mêmes sont toujours constants, mais le pointeur lui-même doit être variable, ne serait-ce que pour pouvoir changer de jour.

  18. #18
    Invité
    Invité(e)
    Par défaut
    Encore une fois merci pour cette explication claire !

    Maintenant, si je rapporte ceci à mon code, grossièrement, cela voudrait dire que je devrais changer mon pointeur dans ma structure par un tableau de chaînes de caractères constant comportant les différents noms des éléments de mon menu et que j'accéderais à ceci via un pointeur initialisé dans ma fonction init ?

    Ensuite, je me demande encore comment traquer le reste des erreurs de mémoires ...

    Merci et bonne journée

    TcodingT

  19. #19
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par TcodingT Voir le message
    Encore une fois merci pour cette explication claire !

    Maintenant, si je rapporte ceci à mon code, grossièrement, cela voudrait dire que je devrais changer mon pointeur dans ma structure par un tableau de chaînes de caractères constant comportant les différents noms des éléments de mon menu et que j'accéderais à ceci via un pointeur initialisé dans ma fonction init ?
    Non, c'est plus simple que cela. Puisque tu n'utilises que des chaînes constantes qui n'ont pas à être modifiées en elles-mêmes au cours de l'exécution (même si tu peux choisir l'une d'entre elles à ta convenance et en changer), alors il faut utiliser des pointeurs appropriés :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    typedef struct link
    {
        char const *name;
        char focus;
        SDL_Surface* link;
        SDL_Texture* link_tex;
        SDL_Rect link_pos;
        TTF_Font* link_font;
    }link_s;
    Maintenant, ce n'est pas cela qui aurait fait planter ton programme. Mais au moins, si une portion de ton programme y écrit par erreur, le compilateur sera en mesure de le détecter.

    Ensuite, je me demande encore comment traquer le reste des erreurs de mémoires ...
    Il n'y a pas de moyen simple de le faire car valgrind détecte beaucoup d'erreurs qui surviennent au sein des fonctions des pilotes eux-mêmes ! Les pilotes nVidia (officiels) pour Linux, par exemple, sont réputés sur les forums pour laisser beaucoup de mémoire en plan, à charge au système de nettoyer le tout. Je peux constater que c'est vrai sur ma propre machine mais, là encore, difficile de dire à chaque fois si c'est dû au pilote lui-même, à la SDL qui l'appelle ou aux données initiales de ton propre programme.

    Donc, il faut y aller par dichotomies successives : commence par mettre en commentaire (avec « #ifdef 0 … #endif », c'est ce qu'il y a de plus simple) tout ce qui se trouve entre « SDL_Init() TTF_Init() » et « TTF_Quit() SDL_Quit() », recompile, et vois si le problème se pose toujours. Si non, restreins la zone en commentaire en déplaçant le début après « CreateWindow() » et sa fin avant « DestroyWindow() ». Procède ainsi de proche en proche jusqu'à ce que le problème réapparaisse.

  20. #20
    Invité
    Invité(e)
    Par défaut
    Très bien, merci à tous et pour tout !

    (Même si je n'ai pas résolu le problème j'ai la marche à suivre je marque donc ce sujet résolu)

    En espérant que vous avez passé de bonnes fêtes

    Bonne soirée

    TcodingT

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 22/07/2009, 20h21
  2. Process terminated with status -1073741819
    Par lordskelethom dans le forum C++
    Réponses: 2
    Dernier message: 25/05/2009, 10h07
  3. Réponses: 1
    Dernier message: 02/02/2009, 18h41
  4. Réponses: 3
    Dernier message: 07/06/2007, 19h26
  5. Process terminated with status 1 signifaction ?
    Par haydens dans le forum GTK+ avec C & C++
    Réponses: 2
    Dernier message: 31/05/2007, 00h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo