LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-02-2012, 07:26 PM   #1
errigour
Member
 
Registered: May 2009
Posts: 366

Rep: Reputation: 6
free freeing data twice or data that shoulnd't be freed


Maybe I'm declaring top->desc wrong but where I don't see it


Code:
#include <stdlib.h>
#include <stdio.h>
#include<string.h>

struct areas
{
     int width;                    /* Area's map width                     */
     int height;                   /* Area's map height                    */

     char *name;                   /* Area's Name                          */
     char *descr;                  /* Area's Description                   */

     struct areas *next;           /* Structure for accessing all areas    */
};

int main()
{
     FILE *fp;

     struct areas *top;
     struct areas *next;

     short int x, y, width = 0, height = 0;
     char *ch;
     char name[100] = "NULL";
     char desc[10000] = "NULL";

     short int start = 0;

     ch = malloc(1);
     ch[1] = '\0';

     if ((fp = fopen(".hometown.map", "r")) == NULL)
          printf("Error opening hometown.map\r\n");

     fgets(name, 100, fp);
     name[strlen(name) - 1] = 0x00;

     for ( y = 0; ; y++)
     {
          if ( start == 1)
               height++;
          for ( x = 0; *ch != '\n'; x++)
          {
               fread(ch, 1, 1, fp);

               if(feof(fp)) { x = -1; width--; break;}

               if ( *ch == '~' ) start = 1;
               if ( height == 1) width++;

               printf("%c", ch[0]);
          }
          *ch = 0x00;
          if ( x == -1) break;
     }
     free(ch);
     fclose(fp);

     top = malloc(sizeof(top));

     top->width = width;
     top->height = height;

     top->name = malloc(strlen(name) + 1);
     strncpy(top->name, name, strlen(name));
     top->name[strlen(name) + 1] = 0x00;

     top->descr = malloc(strlen(desc) + 1);
     strncpy(top->descr, desc, strlen(desc));
     top->descr[strlen(desc) + 1] = 0x00;

     printf("\r\n");
     printf("top->width = %d\r\n", top->width);
     printf("top->height = %d\r\n", top->height);
     printf("top->name = %s\r\n", top->name);
     printf("top->description = %s\r\n", top->descr);
     printf("length of name: %d\r\n", strlen(name));
     printf("length of desc: %d\r\n", strlen(desc));
     free(top->descr);
     printf("descr freed\r\n");
     free(top->name);
     printf("name freed\r\n");
     free(top);
     printf("top freed\r\n");
}


---------- Post added 10-02-12 at 08:26 PM ----------

on this topic anyone know of a better debugger for linux?

---------- Post added 10-02-12 at 08:27 PM ----------

or how to debug this problem better?
 
Old 10-02-2012, 07:58 PM   #2
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,771

Rep: Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070
Code:
     ch = malloc(1);
     ch[1] = '\0';
You're writing past the end there.

Quote:
how to debug this problem better?
valgrind is often helpful for this kind of thing.
 
Old 10-02-2012, 08:21 PM   #3
errigour
Member
 
Registered: May 2009
Posts: 366

Original Poster
Rep: Reputation: 6
still crashing
 
Old 10-02-2012, 08:30 PM   #4
errigour
Member
 
Registered: May 2009
Posts: 366

Original Poster
Rep: Reputation: 6
also if you add top->next = NULL;

after line

top->descr[strlen(desc) + 1] = 0x00;

top->name equals nothing. wierd.

now it seems to be when freeing name

Last edited by errigour; 10-02-2012 at 08:33 PM.
 
Old 10-02-2012, 11:44 PM   #5
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Hi.

Let's debug your program using valgrind.
Code:
$ gcc -g crash.c  && valgrind ./a.out
crash.c: In function ‘main’:
crash.c:78:6: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘size_t’ [-Wformat]
crash.c:79:6: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘size_t’ [-Wformat]
==5524== Memcheck, a memory error detector
==5524== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==5524== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==5524== Command: ./a.out
==5524== 
==5524== Invalid write of size 1
==5524==    at 0x40091E: main (crash.c:31)
==5524==  Address 0x51f1041 is 0 bytes after a block of size 1 alloc'd
==5524==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5524==    by 0x40090B: main (crash.c:30)
==5524== 
==5524== Invalid read of size 4
==5524==    at 0x4EA10EE: fgets (iofgets.c:52)
==5524==    by 0x400968: main (crash.c:36)
==5524==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==5524== 
==5524== 
==5524== Process terminating with default action of signal 11 (SIGSEGV)
==5524==  Access not within mapped region at address 0x0
==5524==    at 0x4EA10EE: fgets (iofgets.c:52)
==5524==    by 0x400968: main (crash.c:36)
==5524==  If you believe this happened as a result of a stack
==5524==  overflow in your program's main thread (unlikely but
==5524==  possible), you can try to increase the size of the
==5524==  main thread stack using the --main-stacksize= flag.
==5524==  The main thread stack size used in this run was 8388608.
Error opening hometown.map
==5524== 
==5524== HEAP SUMMARY:
==5524==     in use at exit: 1 bytes in 1 blocks
==5524==   total heap usage: 2 allocs, 1 frees, 569 bytes allocated
==5524== 
==5524== LEAK SUMMARY:
==5524==    definitely lost: 0 bytes in 0 blocks
==5524==    indirectly lost: 0 bytes in 0 blocks
==5524==      possibly lost: 0 bytes in 0 blocks
==5524==    still reachable: 1 bytes in 1 blocks
==5524==         suppressed: 0 bytes in 0 blocks
==5524== Rerun with --leak-check=full to see details of leaked memory
==5524== 
==5524== For counts of detected and suppressed errors, rerun with: -v
==5524== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)
Okay, we have invalid write on line 31:
Code:
     ch = malloc(1);
     ch[1] = '\0';     // line 31
This bug has already been discovered by ntubski. And we will see that the same error occurs two more times in the program. You allocated only one byte for ch, but on the next line (N31) you try to assign zero value to the second element of string ch. C uses zero-based indexing: first element has index 0, second element -- 1 etc. So to fix this bug you should write
Code:
     ch = malloc(1);
     ch[0] = '\0';     // line 31
(BTW why you use one-character dynamic string here instead of just char ch;?)
Fixed.

Repeat the procedure:
Code:
$ gcc -g crash.c  && valgrind ./a.out 
crash.c: In function ‘main’:
crash.c:78:6: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘size_t’ [-Wformat]
crash.c:79:6: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘size_t’ [-Wformat]
==5568== Memcheck, a memory error detector
==5568== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==5568== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==5568== Command: ./a.out
==5568== 
==5568== Invalid read of size 4
==5568==    at 0x4EA10EE: fgets (iofgets.c:52)
==5568==    by 0x400964: main (crash.c:36)
==5568==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==5568== 
==5568== 
==5568== Process terminating with default action of signal 11 (SIGSEGV)
==5568==  Access not within mapped region at address 0x0
==5568==    at 0x4EA10EE: fgets (iofgets.c:52)
==5568==    by 0x400964: main (crash.c:36)
==5568==  If you believe this happened as a result of a stack
==5568==  overflow in your program's main thread (unlikely but
==5568==  possible), you can try to increase the size of the
==5568==  main thread stack using the --main-stacksize= flag.
==5568==  The main thread stack size used in this run was 8388608.
Error opening hometown.map
==5568== 
==5568== HEAP SUMMARY:
==5568==     in use at exit: 1 bytes in 1 blocks
==5568==   total heap usage: 2 allocs, 1 frees, 569 bytes allocated
==5568== 
==5568== LEAK SUMMARY:
==5568==    definitely lost: 0 bytes in 0 blocks
==5568==    indirectly lost: 0 bytes in 0 blocks
==5568==      possibly lost: 0 bytes in 0 blocks
==5568==    still reachable: 1 bytes in 1 blocks
==5568==         suppressed: 0 bytes in 0 blocks
==5568== Rerun with --leak-check=full to see details of leaked memory
==5568== 
==5568== For counts of detected and suppressed errors, rerun with: -v
==5568== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
What's wrong with line 36:
Code:
     fgets(name, 100, fp);
? Looks good. But couple of lines above we see
Code:
     if ((fp = fopen(".hometown.map", "r")) == NULL)
          printf("Error opening hometown.map\r\n");
And we also see your error message "Error opening hometown.map". There are no such file as ".hometown.map" in my /tmp directory, naturally. The program tells us that there are no such file and just continues execution! Not good!
Code:
     if ((fp = fopen(".hometown.map", "r")) == NULL) {
          printf("Error opening hometown.map\r\n");
	  free(ch); // to calm down valgrind
	  exit(EXIT_FAILURE);
     }
Fixed.
Continue:
Code:
$ touch .hometown.map
$ gcc -g crash.c  && valgrind ./a.out 
crash.c: In function ‘main’:
crash.c:81:6: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘size_t’ [-Wformat]
crash.c:82:6: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘size_t’ [-Wformat]
==5610== Memcheck, a memory error detector
==5610== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==5610== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==5610== Command: ./a.out
==5610== 
==5610== Invalid write of size 8
==5610==    at 0x400B72: main (crash.c:68)
==5610==  Address 0x51f1318 is 0 bytes after a block of size 8 alloc'd
==5610==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5610==    by 0x400B06: main (crash.c:63)
==5610== 
==5610== Invalid read of size 8
==5610==    at 0x400BAE: main (crash.c:69)
==5610==  Address 0x51f1318 is 0 bytes after a block of size 8 alloc'd
==5610==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5610==    by 0x400B06: main (crash.c:63)
==5610== 
==5610== Invalid read of size 8
==5610==    at 0x400BC4: main (crash.c:70)
==5610==  Address 0x51f1318 is 0 bytes after a block of size 8 alloc'd
==5610==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5610==    by 0x400B06: main (crash.c:63)
==5610== 
==5610== Invalid write of size 1
==5610==    at 0x400BFC: main (crash.c:70)
==5610==  Address 0x51f1364 is 0 bytes after a block of size 4 alloc'd
==5610==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5610==    by 0x400B67: main (crash.c:68)
==5610== 
==5610== Invalid write of size 8
==5610==    at 0x400C45: main (crash.c:72)
==5610==  Address 0x51f1320 is 8 bytes after a block of size 8 alloc'd
==5610==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5610==    by 0x400B06: main (crash.c:63)
==5610== 
==5610== Invalid read of size 8
==5610==    at 0x400C87: main (crash.c:73)
==5610==  Address 0x51f1320 is 8 bytes after a block of size 8 alloc'd
==5610==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5610==    by 0x400B06: main (crash.c:63)
==5610== 
==5610== Invalid read of size 8
==5610==    at 0x400C9D: main (crash.c:74)
==5610==  Address 0x51f1320 is 8 bytes after a block of size 8 alloc'd
==5610==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5610==    by 0x400B06: main (crash.c:63)
==5610== 
==5610== Invalid write of size 1
==5610==    at 0x400CD8: main (crash.c:74)
==5610==  Address 0x51f13b5 is 0 bytes after a block of size 5 alloc'd
==5610==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5610==    by 0x400C3A: main (crash.c:72)
==5610== 
==5610== Invalid read of size 8
==5610==    at 0x400D27: main (crash.c:79)
==5610==  Address 0x51f1318 is 0 bytes after a block of size 8 alloc'd
==5610==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5610==    by 0x400B06: main (crash.c:63)
==5610== 
==5610== Conditional jump or move depends on uninitialised value(s)
==5610==    at 0x4E7D3D1: vfprintf (vfprintf.c:1630)
==5610==    by 0x4E858F8: printf (printf.c:35)
==5610==    by 0x400D3F: main (crash.c:79)
==5610== 
==5610== Invalid read of size 8
==5610==    at 0x400D47: main (crash.c:80)
==5610==  Address 0x51f1320 is 8 bytes after a block of size 8 alloc'd
==5610==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5610==    by 0x400B06: main (crash.c:63)
==5610== 
==5610== Conditional jump or move depends on uninitialised value(s)
==5610==    at 0x4E7D3D1: vfprintf (vfprintf.c:1630)
==5610==    by 0x4E858F8: printf (printf.c:35)
==5610==    by 0x400D5F: main (crash.c:80)
==5610== 
==5610== Invalid read of size 8
==5610==    at 0x400DEE: main (crash.c:83)
==5610==  Address 0x51f1320 is 8 bytes after a block of size 8 alloc'd
==5610==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5610==    by 0x400B06: main (crash.c:63)
==5610== 
==5610== Invalid read of size 8
==5610==    at 0x400E0B: main (crash.c:85)
==5610==  Address 0x51f1318 is 0 bytes after a block of size 8 alloc'd
==5610==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5610==    by 0x400B06: main (crash.c:63)
==5610== 

top->width = -1
top->height = 0
top->name = NUL
top->description = NULL
length of name: 3
length of desc: 4
descr freed
name freed
top freed
==5610== 
==5610== HEAP SUMMARY:
==5610==     in use at exit: 0 bytes in 0 blocks
==5610==   total heap usage: 5 allocs, 5 frees, 586 bytes allocated
==5610== 
==5610== All heap blocks were freed -- no leaks are possible
==5610== 
==5610== For counts of detected and suppressed errors, rerun with: -v
==5610== Use --track-origins=yes to see where uninitialised values come from
==5610== ERROR SUMMARY: 14 errors from 14 contexts (suppressed: 2 from 2)
Oh no, not again..
Line 68:
Code:
     top->name = malloc(strlen(name) + 1);
Can we write to top->name? Did we allocated space for it?
Code:
     top = malloc(sizeof(top));
Hmm.. Yes? NO! What is top?
Code:
     struct areas *top;
It is a pointer, its size is something like 4 or 8 bytes. Hardly enough.. One should write
Code:
     top = malloc(sizeof(struct areas));
Fixed.

Continue:
Code:
$ gcc -g crash.c  && valgrind ./a.out 
crash.c: In function ‘main’:
crash.c:81:6: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘size_t’ [-Wformat]
crash.c:82:6: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘size_t’ [-Wformat]
==5866== Memcheck, a memory error detector
==5866== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==5866== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==5866== Command: ./a.out
==5866== 
==5866== Invalid write of size 1
==5866==    at 0x400BFC: main (crash.c:70)
==5866==  Address 0x51f1374 is 0 bytes after a block of size 4 alloc'd
==5866==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5866==    by 0x400B67: main (crash.c:68)
==5866== 
==5866== Invalid write of size 1
==5866==    at 0x400CD8: main (crash.c:74)
==5866==  Address 0x51f13c5 is 0 bytes after a block of size 5 alloc'd
==5866==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5866==    by 0x400C3A: main (crash.c:72)
==5866== 
==5866== Conditional jump or move depends on uninitialised value(s)
==5866==    at 0x4E7D3D1: vfprintf (vfprintf.c:1630)
==5866==    by 0x4E858F8: printf (printf.c:35)
==5866==    by 0x400D3F: main (crash.c:79)
==5866== 
==5866== Conditional jump or move depends on uninitialised value(s)
==5866==    at 0x4E7D3D1: vfprintf (vfprintf.c:1630)
==5866==    by 0x4E858F8: printf (printf.c:35)
==5866==    by 0x400D5F: main (crash.c:80)
==5866== 

top->width = -1
top->height = 0
top->name = NUL
top->description = NULL
length of name: 3
length of desc: 4
descr freed
name freed
top freed
==5866== 
==5866== HEAP SUMMARY:
==5866==     in use at exit: 0 bytes in 0 blocks
==5866==   total heap usage: 5 allocs, 5 frees, 610 bytes allocated
==5866== 
==5866== All heap blocks were freed -- no leaks are possible
==5866== 
==5866== For counts of detected and suppressed errors, rerun with: -v
==5866== Use --track-origins=yes to see where uninitialised values come from
==5866== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 2 from 2)
Invalid writes on lines 70, 74:
Code:
     top->name = malloc(strlen(name) + 1);
     strncpy(top->name, name, strlen(name));
     top->name[strlen(name) + 1] = 0x00;         // line 70

     top->descr = malloc(strlen(desc) + 1);
     strncpy(top->descr, desc, strlen(desc));
     top->descr[strlen(desc) + 1] = 0x00;        // line 74
Again, you allocate array of strlen(name)+1 bytes and write to the last element, which should be (srtlen(name)+1)-1 = strlen(name):
Code:
     top->name = malloc(strlen(name) + 1);
     strncpy(top->name, name, strlen(name));
     top->name[strlen(name) ] = 0x00;         // line 70

     top->descr = malloc(strlen(desc) + 1);
     strncpy(top->descr, desc, strlen(desc));
     top->descr[strlen(desc) ] = 0x00;        // line 74
Fixed:
Code:
$ gcc -g crash.c  && valgrind ./a.out
crash.c: In function ‘main’:
crash.c:81:6: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘size_t’ [-Wformat]
crash.c:82:6: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘size_t’ [-Wformat]
==5915== Memcheck, a memory error detector
==5915== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==5915== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==5915== Command: ./a.out
==5915== 

top->width = -1
top->height = 0
top->name = NUL
top->description = NULL
length of name: 3
length of desc: 4
descr freed
name freed
top freed
==5915== 
==5915== HEAP SUMMARY:
==5915==     in use at exit: 0 bytes in 0 blocks
==5915==   total heap usage: 5 allocs, 5 frees, 610 bytes allocated
==5915== 
==5915== All heap blocks were freed -- no leaks are possible
==5915== 
==5915== For counts of detected and suppressed errors, rerun with: -v
==5915== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Hurrah!
 
3 members found this post helpful.
Old 10-03-2012, 01:30 AM   #6
errigour
Member
 
Registered: May 2009
Posts: 366

Original Poster
Rep: Reputation: 6
I'm sorry I didn't include .hometown.map I thought I gave you everything you needed to debug and I myself
came up short. I must say I am much oblidged to you, Firstfire. top = malloc(sizeof(struct areas));
was exactly the problem. everything else is actually really cool.

Again thanks to Firstfire. I read it fifteen times and fifteen times I missed it.
And special thanks to Ntubski for pointing out my character.
Sharing my Cool skeleton project:
http://o0oo0.net16.net/shared

ch is a pointer cause fread doesn't like plain characters for some reason.
heres .hometown.map
http://o0oo0.net16.net/shared/.hometown.map

Last edited by errigour; 10-03-2012 at 01:39 AM.
 
Old 10-03-2012, 02:27 AM   #7
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,630

Rep: Reputation: 7265Reputation: 7265Reputation: 7265Reputation: 7265Reputation: 7265Reputation: 7265Reputation: 7265Reputation: 7265Reputation: 7265Reputation: 7265Reputation: 7265
errigour, if you really think that post was helpful, please click on the "Yes" (bottom right corner). Firstfire made a very good job.
 
Old 10-03-2012, 07:40 AM   #8
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,771

Rep: Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070Reputation: 2070
Quote:
Originally Posted by errigour View Post
ch is a pointer cause fread doesn't like plain characters for some reason.
fread() wants an address to write to, you can use the address-of operator, &:
Code:
char ch;
fread(&ch, 1, 1, fp);
Although if you're reading a single character it's easier to use getc():
Code:
int ch; /* getc returns a character or EOF so you need to use an int */
ch = getc(fp);
Oh, and regarding the malloc() for top, you can also use:
Code:
top = malloc(sizeof(*top));
 
Old 10-04-2012, 03:26 AM   #9
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
I can't figure out what you are doing, linked-listing?
I think you are making life very difficult for yourself.

Why are you poncing about with malloc may I ask?
It's a recipe for mistakes avoid if you can.

If you must you can use strdup(3) to copy strings.

If it's a fire-and-forget application don't even waste your time calling free
the OS will recover any allocated space when you exit.

And don't do everything in one main function unless it's very trivial.
And I wouldn't use fread if I can get away with using stdio.h
(Let the OS do the work where you can and use your time for the interesting stuff).

ddd is a good front end for gdb.
 
Old 10-04-2012, 09:34 AM   #10
errigour
Member
 
Registered: May 2009
Posts: 366

Original Poster
Rep: Reputation: 6
well im using malloc because I can't get everything to compile right. I'm being difficult intentionally to master what I cannot do casually.

since you mention ddd maybe you can help me use it.
My program seems to be changing the address of char name[0] to 0x00. or I think because strlen of name = 0;
so how can I use ddd valgrind and gdb to find where the registry error is easily if I can. maybe you could show me an example use of ddd for this.
 
Old 10-04-2012, 11:45 AM   #11
errigour
Member
 
Registered: May 2009
Posts: 366

Original Poster
Rep: Reputation: 6
char area_map[10000][10000];
crashes my program
but when its not there the program runs great
 
Old 10-04-2012, 11:57 AM   #12
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by errigour View Post
char area_map[10000][10000];
crashes my program
but when its not there the program runs great
If you search for other threads on "stack size" I'm sure you can easily find both an explanation of the cause of the crash, and several alternatives for making it work.

One example is:
http://www.linuxquestions.org/questi...2/#post4688720

In the example in that post it is important that the call to increase the stack limit happens before the call to the function that includes the declaration of the large array. I think C99 allows you to declare the large array within a function after doing work, such as increasing the stack limit, earlier in the same function. That might work. With certain added tricks specific to C99, it could work reliably. But in most cases the compiler will move the stack allocation to the beginning of the function, so changing the limit earlier in the same function is not good enough. It needs to be changed in a different function executed before this function is called.

I expect you want that array declared in main() in some program similar to the one at the top of this thread. In C, that makes it very hard to execute code before the function is called. There are other methods, but I suggest you have too much code in main anyway. Consider moving almost everything from main to some other function called by main. I would tend to leave inside main certain steps like opening of required files (".hometown.map") and aborting if those files are missing, then pass the file pointer to the function that takes over most of main's previous job.

Last edited by johnsfine; 10-04-2012 at 12:18 PM.
 
Old 10-04-2012, 01:28 PM   #13
errigour
Member
 
Registered: May 2009
Posts: 366

Original Poster
Rep: Reputation: 6
.hometown.map:
http://o0oo0.net16.net/shared/.hometown.map

Can I ask one more thing here instead of posting:
Code:
     top->area_map = calloc(height, width);
     for( y = 0; y < height; y++)
          for ( x = 0; x < width; x++)
          {
               printf("x: %d, y: %d\r\n", x, y);
               top->area_map[y][x] = area_map[y][x];
          }
the code above height is 501 width is 1001.
top->area_map is
char **area_map

is that a stack problem or am I defining it wrong?
i really gotta know how to do this thanks.

Last edited by errigour; 10-04-2012 at 01:30 PM.
 
Old 10-04-2012, 01:34 PM   #14
errigour
Member
 
Registered: May 2009
Posts: 366

Original Poster
Rep: Reputation: 6
char area_map[500][1000]
it gives a segmentation fault at
top->area_map[0][0] = area_map[0][0];
 
Old 10-04-2012, 01:45 PM   #15
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by errigour View Post
Code:
     top->area_map = calloc(height, width);
...
               top->area_map[y][x] = area_map[y][x];
top->area_map is
char **area_map

is that a stack problem or am I defining it wrong?
You are defining it wrong (or allocating it wrong). It is not a stack problem.

char **area_map together with area_map[y][x] implies area_map points to a vector of pointers and each of those points to a separately allocated vector of data. You could replace the single allocation step with multiple allocations to build up the space implied by your current declaration and access code. Alternately, you could change the declaration to fit your existing allocation and access:

I think that would be:
Code:
typedef char data_row[1001];
struct areas {
...
data_row* area_map;
... };
In ANSI C, that method only works when the width is know at compile time (the height can still be decided at run time). The multi layered allocation lets both width and height be decided at run time. I think C99 and/or some gcc extension lets you use the declaration I suggested and still replace the 1001 with a variable. But I don't program in C99, so I might be confused on that detail.

Last edited by johnsfine; 10-04-2012 at 01:56 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Hang after "Freeing unused kernel memory (...)kb freed" qcinski Linux From Scratch 0 08-01-2009 12:12 PM
The booting hang on "Freeing unused kernel memory : 168k freed" Brian Lu Linux - Software 1 05-27-2008 08:45 PM
'Freeing Unused Kernel Memory: 224k Freed - Laptop Hangs nutnut Linux - Laptop and Netbook 1 10-21-2005 07:09 PM
Freeing unused kernel memory: 136k freed apenguinlinux Debian 8 08-08-2005 03:30 PM
Freeing unused kernel memory: 228k freed bodedeb Linux - General 8 10-28-2003 03:59 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:42 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration