N-PN White-Hat Project
[C] SegFault > 6 - Version imprimable

+- N-PN White-Hat Project (https://dev.n-pn.fr/forum)
+-- Forum : Programmation (https://dev.n-pn.fr/forum/forumdisplay.php?fid=72)
+--- Forum : Langages compilés (https://dev.n-pn.fr/forum/forumdisplay.php?fid=25)
+--- Sujet : [C] SegFault > 6 (/showthread.php?tid=2594)



[C] SegFault > 6 - Sh4dows - 06-01-2013

Bonjour,
J'ai une fonction qui doit prendre le premier élément d'un tableau A et le mettre dans le second B, (A[0] dans B[0]). Or j'ai un "segfault" ou un "glibc free.." dès lors que mon tableau A dépasse 6 en taille. Mes deux tableaux sont des tableaux de int.

Pour information c'est un de mes projets d'école, je ne comprend juste pas d'ou provient mon erreur dans cette fonction..

Exemple :
Code :
A = 1 2 3 4 5
B =

Sortie de ma fonction..

A = 2 3 4 5
B = 1

Ensuite voici la fonction qui pose problème :
Code C :

void    take_b(struct s_data *vars)
{
  int    i;
  int    *temp_a;
  int    *temp_b;

  if (vars->size_a >= 1)
    {
      temp_b = backup(vars->tab_b, vars->size_b);
      vars->size_b += 1;
      free(vars->tab_b);
      if ((vars->tab_b = malloc(sizeof(int) * vars->size_b)) != NULL)
    {
      i = 1;
      vars->tab_b[i - 1] = vars->tab_a[i - 1];
      temp_a = backup(vars->tab_a, vars->size_a);
      while (i < vars->size_b)
        {
          vars->tab_b[i] = temp_b[i - 1];
          i += 1;
        }
      i = 0;
      vars->size_a -= 1;
      free(vars->tab_a);
      vars->tab_a = malloc(sizeof(int) * vars->size_a);
      while (i < vars->size_a + 1)
        {
          vars->tab_a[i] = temp_a[i + 1];
          i += 1;
        }
      free(temp_b);
      free(temp_a);
    }
    }
}
 


Mon push_swap.h :
Code C :

#ifndef _PUSH_SWAP_
#define _PUSH_SWAP_

struct    s_data
{
  int    size_a;
  int    size_b;
  int    *tab_a;
  int    *tab_b;
};

#endif
 


Et mon main.c avec main() et backup() !
Code C :

#include <stdlib.h>
#include <stdio.h>
#include "push_swap.h"

int            main(int argc, char *argv[])
{
  int            i;
  struct s_data        *vars;

  if (argc < 2)
    return (0);
  if ((vars = malloc(sizeof(struct s_data))) == NULL)
    return (0);
  vars->size_a = argc - 1;
  vars->size_b = 0;
  if ((vars->tab_a = malloc(sizeof(int) * vars->size_a)) == NULL)
    return (0);
  if ((vars->tab_b = malloc(sizeof(int) * vars->size_b)) == NULL)
    return (0);
  i = 0;
  while (i < argc - 1)
    {
      vars->tab_a[i] = atoi(argv[i + 1]);
      i += 1;
    }
 
  /* JUST FOR TEST MY FUNC */
  i = 0;
  while (i < 1)
  {
      take_b(vars);
      i += 1;
  }

  printf("\n");
  free(vars->tab_a);
  free(vars->tab_b);
  free(vars);
  return (0);
}

int            *backup(int *tab, int sz)
{
  int            i;
  int            *new;

  if ((new = malloc(sizeof(int) * sz)) != NULL)
    {
      i = 0;
      while (i < sz)
    {
      new[i] = tab[i];
      i += 1;
    }
      return (new);
    }
  return (tab);
}
 


Je récupère tous les arguments passé au programme, puis je les transforme en int via atoi() (man pour plus d'infos) et les stocke dans mon tableau présent dans ma structure. Dans cette fameuse structure, il y a tableau A et B, ainsi que deux variables représentant leur taille.

La fonction backup fais une sauvegarde d'un tableau !!

Donc en en appellant mon programme comme ceci :
./a.out 1 2 3 4 Tous fonctionne.
Mais en faisant ceci ./a.out 1 2 3 4 5 6 7 J'ai une des erreurs cité au début Huh

Si vous voyez pourquoi je segfault ??
Merci d'avance Tongue


RE: [C] SegFault > 6 - ark - 06-01-2013

Les AERs sont la pour ça ! (Et au passage t'es pas a la norme :3)

Bref, anyway, use gdb pour donner plus d'information (compile en -g3 d'abord (et pense a l'enlever avant le rendu...))

Et sinon, go use des listes doublement chaînées circulaires Big Grin


RE: [C] SegFault > 6 - Sh4dows - 06-01-2013

*** glibc detected *** /home/XXX/Documents/Projets/PushSwap/a.out: free(): invalid next size (fast): 0x00000000006030d0 ***
a.out: malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff7a80d95 in raise () from /lib64/libc.so.6


RE: [C] SegFault > 6 - ark - 06-01-2013

hmm, tape bt dans gdb après qu'il ai plante et poste le résultat.


RE: [C] SegFault > 6 - Sh4dows - 06-01-2013

#0 0x00007ffff7a80d95 in raise () from /lib64/libc.so.6
#1 0x00007ffff7a822ab in abort () from /lib64/libc.so.6
#2 0x00007ffff7ac1d3d in __malloc_assert () from /lib64/libc.so.6
#3 0x00007ffff7ac4c75 in _int_malloc () from /lib64/libc.so.6
#4 0x00007ffff7ac79ae in calloc () from /lib64/libc.so.6
#5 0x00007ffff7de6a2e in _dl_new_object () from /lib64/ld-linux-x86-64.so.2
#6 0x00007ffff7de21d6 in _dl_map_object_from_fd () from /lib64/ld-linux-x86-64.so.2
#7 0x00007ffff7de3fd7 in _dl_map_object () from /lib64/ld-linux-x86-64.so.2
#8 0x00007ffff7dedc2b in dl_open_worker () from /lib64/ld-linux-x86-64.so.2
#9 0x00007ffff7de9c36 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#10 0x00007ffff7ded7ca in _dl_open () from /lib64/ld-linux-x86-64.so.2
#11 0x00007ffff7b5e410 in do_dlopen () from /lib64/libc.so.6
#12 0x00007ffff7de9c36 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#13 0x00007ffff7b5e4af in dlerror_run () from /lib64/libc.so.6
#14 0x00007ffff7b5e517 in __libc_dlopen_mode () from /lib64/libc.so.6
#15 0x00007ffff7b398e5 in init () from /lib64/libc.so.6
#16 0x00007ffff7b39a2d in backtrace () from /lib64/libc.so.6
#17 0x00007ffff7abc9af in __libc_message () from /lib64/libc.so.6
#18 0x00007ffff7ac26d6 in malloc_printerr () from /lib64/libc.so.6
#19 0x00000000004016eb in take_b (vars=0x603010) at take.c:79
#20 0x00000000004009d5 in main (argc=9, argv=0x7fffffffde18) at push_swap.c:89


RE: [C] SegFault > 6 - Sh4dows - 06-01-2013

J'ai mis pas mal de temps, mais tous fonctionne Smile Merci à @Ark, j'ai appris pas mal d'astuces avec GDB.
C'était bien la fonction take_b() au dernier while qui produisait l'Erreur de Segmentation !!

Code C :

void    take_b(struct s_data *vars)
{
  int    i;
  int    *tmp_b;

  if (vars->size_a >= 1)
    {
      tmp_b = backup(vars->tab_b, vars->size_b);
      vars->size_b += 1;
      free(vars->tab_b);
      vars->tab_b = malloc(sizeof(int) * vars->size_b);
      i = 1;
      vars->tab_b[0] = vars->tab_a[0];
      if (vars->size_b > 1)
    {
      while (i < vars->size_b)
        {
          vars->tab_b[i] = tmp_b[i - 1];
          i += 1;
        }
    }
      free(tmp_b);
      take_b_ext(vars);
    }
}

void    take_b_ext(struct s_data *vars)
{
  int    i;
  int    *tmp_a;

  tmp_a = backup(vars->tab_a, vars->size_a);
  free(vars->tab_a);
  vars->tab_a = malloc(sizeof(int) * vars->size_a);
  i = 0;
  while (i + 1 < vars->size_a)
    {
      vars->tab_a[i] = tmp_a[i + 1];
      i += 1;
    }
  vars->size_a -= 1;
  free(tmp_a);
}
 


PS : Pensez à checker les mallocs Smile