realloc(): invalid next size

Odpowiedz Nowy wątek
2013-06-26 16:37
0

Witajcie
Jestem w trakcie pisania programu w C, który ma zczytać nieokreśloną ilość liczb o różnej długości zapisanych w pliku tekstowym. Poniżej prezentuję kod oraz błąd, który pojawia się w konsoli po uruchomieniu poprawnie skompilowanego programu. Czy mógłbym liczyć na pomoc w rozwiązaniu problemu?

 #include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

char* getNum (FILE *f)
{
  int size=1;
  int count;
  int len;
  char* num;
  int c;

  num=malloc(sizeof(char)*size);
  if (num==NULL) return NULL;
  len=size;
  count=0;
  while (isdigit(c=fgetc(f)))
  {
    num[count]=c;
    count++;
    if (count>=len)
    {
      len+=size;
      num=realloc(num,len*sizeof(char));
    }
  }
  ungetc(c,f);
  num[count]='\0';
  return num;
}

int main (int argc, char* argv[])
{
  FILE *in;
  char** n;
  int size=1;
  int count;
  int len;
  int i;

  if (argc!=2) exit(2);
  in=fopen(argv[1],"r");
  if (!in) exit(3);

  n=malloc(sizeof(char)*size);
  if (n==NULL) abort();
  len=size;
  count=0;
  while (!feof(in))
  {
    n[count]=getNum(in);
    if (n==NULL)
    {
      printf ("Malloc failed\n");
      break;
    }
    count++;
    if (count>=len)
    {
      len+=size;
      n=realloc(n,len*sizeof(char));
    }
    n[count]='\0';
  }

  for (i=0;i<count;i++)
  {
  printf ("%s",n[count]);
  }
  free(n);
  return 0;
}

*** glibc detected *** ./prog: realloc(): invalid next size: 0x087e8170 ***

edytowany 1x, ostatnio: Pramus, 2013-06-26 16:38

Pozostało 580 znaków

2013-06-26 16:41
0

Wygląda na to, jakbyś chciał zaalokować blok o zbyt dużym rozmiarze.
A zresztą, użyj debuggera i się przekonaj!


Pozostało 580 znaków

2013-06-26 17:15
0
Patryk27 napisał(a):

Wygląda na to, jakbyś chciał zaalokować blok o zbyt dużym rozmiarze.
A zresztą, użyj debuggera i się przekonaj!

Oto co śpiewa mi valgrind:

==3049== Memcheck, a memory error detector
==3049== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==3049== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==3049== Command: ./sort infile
==3049== 
==3049== Invalid write of size 4
==3049==    at 0x80487F1: main (sort.c:51)
==3049==  Address 0x41f61b8 is 0 bytes inside a block of size 1 alloc'd
==3049==    at 0x402BB7A: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3049==    by 0x80487B0: main (sort.c:45)
==3049== 
==3049== Invalid write of size 4
==3049==    at 0x8048848: main (sort.c:63)
==3049==  Address 0x41f7cc4 is 2 bytes after a block of size 2 alloc'd
==3049==    at 0x402BC70: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3049==    by 0x8048832: main (sort.c:61)
==3049== 

valgrind: m_mallocfree.c:266 (mk_plain_bszB): Assertion 'bszB != 0' failed.
valgrind: This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata.  If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away.  Please try that before reporting this as a bug.

==3049==    at 0x3803D043: ??? (in /usr/lib/valgrind/memcheck-x86-linux)
==3049==    by 0x3803D152: ??? (in /usr/lib/valgrind/memcheck-x86-linux)
==3049==    by 0x380007B3: ??? (in /usr/lib/valgrind/memcheck-x86-linux)
==3049==    by 0x3804A760: ??? (in /usr/lib/valgrind/memcheck-x86-linux)
==3049==    by 0x3808441B: ??? (in /usr/lib/valgrind/memcheck-x86-linux)
==3049==    by 0x380161B2: ??? (in /usr/lib/valgrind/memcheck-x86-linux)
==3049==    by 0x38016395: ??? (in /usr/lib/valgrind/memcheck-x86-linux)
==3049==    by 0x38086C6A: ??? (in /usr/lib/valgrind/memcheck-x86-linux)
==3049==    by 0x38098BE7: ??? (in /usr/lib/valgrind/memcheck-x86-linux)

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable
==3049==    at 0x402BB7A: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3049==    by 0x80486A7: getNum (sort.c:13)
==3049==    by 0x80487F0: main (sort.c:51)

Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.

If that doesn't help, please report this bug to: www.valgrind.org

In the bug report, send all the above text, the valgrind
version, and what OS and version you are using.  Thanks.

Pozostało 580 znaków

2013-06-26 17:33
0
  1. Po kiego masz ten ungets?
  2. W malloc i realloc nie zawsze sizeof(char) - zaś rozmiar elementu tablicy.
  3. Jak masz pętle po i to wyświetlaj to co masz pod i

http://ideone.com/yPQnL6


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2013-06-27 18:18
0

Dzięki!
Z Twoją pomocą Dragon udało mi się to ogarnąć, ale teraz mam kolejne pytanie. Jak można domyślić się po nazwie pliku, otrzymane wartości muszę posortować. Jest to jednak dwuwymiarowa tablica gdzie pierwszym wymiarem jest cała liczba, a drugim poszczególne cyfry. No i teraz pytanie: jak posortować tablicę względem pierwszego tylko wymiaru nie zaburzając kolejności w drugim? (A więc jak pozamieniać miejscami liczby nie ruszając przy tym cyfr je tworzących?)

Pozostało 580 znaków

2013-06-27 18:23
0

wymieniasz tylko same wskaźniki: http://www.cplusplus.com/reference/cstdlib/qsort/


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2013-06-28 12:03
0
int compare (const void * a, const void * b)
{
    int _a = *(int*)a;
    int _b = *(int*)b;
    if(_a < _b) return -1;
    else if(_a == _b) return 0;
    else return 1;
}
     qsort (n, count, sizeof(char*), compare);

Co jest nie tak z taką funkcją porównującą/wywoływaniem qsorta?

Zależy od tego jak zadeklarowane n - _13th_Dragon 2013-06-28 13:28

Pozostało 580 znaków

2013-06-30 13:48
0

Cały kod:

 #include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

char *getNum(FILE *f)
  {
   char* num;
   int count;
   int c;

   num=malloc(1);
   count=0;
   while(isdigit(c=fgetc(f)))
     {
      num[count]=c;
      num=realloc(num,++count);
     }
     //if (!isdigit(c)) return NULL;
   num[count]='\0';
   return num;
  }

int compare (const void * a, const void * b)
{
    int _a = *(int*)a;
    int _b = *(int*)b;
    if(_a < _b) return -1;
    else if(_a == _b) return 0;
    else return 1;
}

int main(int argc, char* argv[])
  {
   FILE *in;
   char** n;
   int count;
   int i;

  if (argc!=2) exit(2);
  in=fopen(argv[1],"r");
  if (!in) exit(3);

   n=NULL;
   count=0;
   while(!feof(in))
     {
      n=realloc(n,(count+1)*sizeof(char*));
      n[count++]=getNum(in);
     }
     qsort (n, count, sizeof(char*), compare);

   for(i=0;i<count;++i)
     {
      if (n[i][0]!='\0') printf ("%s\n",n[i]);
     }
   free(n);
   return 0;
  }

Pozostało 580 znaków

2013-06-30 14:05
0
int compare (const void *a, const void *b)
  {
   return strcmp(*(const char**)a,*(const char**)b);
  }

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2013-06-30 14:17
0

Dzięki wielkie, teraz w miarę działa, ale z pewnym zastrzeżeniem. Mianowicie output wygląda tak:

0001234
123456789887878888888888777665564533353455523453535 <---Nieco za wysoko ;)
2345345555555555554435435345345353535353453452
2345345555555555554435435345345353535353453453

Pozostało 580 znaków

2013-06-30 14:22
0

Bo masz sortowanie napisów jeżeli chcesz sortować to jako liczby to musisz to odpowiednio zaimplementować w funkcji compare


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Wiec najlepiej by chyba bylo porownac ilosc elementow poszczegolnych liczb tylko jak to teraz zrobic skoro operuje wskaznikami, a liczba elementow liczb jest po drodze zatracana i nieprzypisana w zaden sposob do konkretnych liczb? - Pramus 2013-06-30 15:01
Właśnie sobie uświadomiłem, że to mnie nie urządza, bo liczby mogą zaczynać się od zer i sama dlugosc liczby nie ma wplywu na jej pozycje po sortowaniu... - Pramus 2013-06-30 18:26

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 0, botów: 1

Robot: CCBot