Segmentation fault

Reply

Join Date: Dec 2007
Posts: 236
Reputation: TheBeast32 is on a distinguished road 
Solved Threads: 6
TheBeast32's Avatar
TheBeast32 TheBeast32 is offline Offline
Posting Whiz in Training

Segmentation fault

 
0
  #1
Jul 21st, 2009
Hi, I'm making a little program that will send email. I am fine with the sockets, but I keep getting a segmentation fault and I don't know why. I'm trying to make a loop that will let the user enter the data for the email, ending with a '.' on its own line (like when using an smtp server). I'm on windows using cygwin.

  1. char *data, ch;
  2. char newline;
  3. unsigned int datalen;
  4.  
  5. data = (char*)calloc(1, sizeof(char));
  6. newline = 1;
  7. datalen = 0;
  8.  
  9. while (1)
  10. {
  11. ch = fgetc(stdin);
  12. realloc(data, ++datalen * sizeof(char));
  13. *(data + datalen - 1) = ch;
  14.  
  15. if (newline)
  16. {
  17. if (ch == '.')
  18. {
  19. realloc(data, ++datalen * sizeof(char));
  20. *(data + datalen - 1) = '\n';
  21. break;
  22. }
  23. else if (ch != '\n')
  24. {
  25. newline = 0;
  26. }
  27. }
  28. else
  29. {
  30. if (ch == '\n')
  31. {
  32. newline = 1;
  33. }
  34. }
  35. }

Here's my output using gdb:
GNU gdb 5.2.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-mingw32"...(no debugging symbols found)...
(gdb) run
Starting program: g:\C\MailClient/./mail.exe

Program received signal SIGSEGV, Segmentation fault.
0x7c80a6c2 in _cygheap_end1 ()
(gdb)

I get the segmentation fault after I enter my 13th character.
"Always program as if the person who will be maintaining your program is a violent psychopath that knows where you live."
--Martin Golding
Reply With Quote Quick reply to this message  
Join Date: Jun 2009
Posts: 830
Reputation: wildgoose is a name known to all wildgoose is a name known to all wildgoose is a name known to all wildgoose is a name known to all wildgoose is a name known to all wildgoose is a name known to all 
Solved Threads: 94
wildgoose's Avatar
wildgoose wildgoose is offline Offline
Practically a Posting Shark

Re: Segmentation fault

 
0
  #2
Jul 21st, 2009
Why are you mixing calloc's with realloc's.

Primarily Realloc() does not always stretch the same memory!!!! It returns the pointer to the new (or stretched) memory. In your case it has stretched it as much as it could around character 13 the reallocated a new block of memory, copied your data then destroyed your memory. You never reset your pointer by...
  1. data = realloc( data, +datalen *sizeof(char) );
...so you accessed memory that nolonger existed!


Why are you chewing on memory one character at a time.
Either use a large enough static buffer, or allocate a single array buffer malloc or new, NOT a two dimensional buffer using calloc!

Also note that you are leaving no room for a possible ASCIIz terminator when you've finished copying your ASCII.

And granted your buffer allocations are pretty short, but realloc CAN fail! So why aren't you checking for NULL return?
Last edited by wildgoose; Jul 21st, 2009 at 3:12 pm.
Reply With Quote Quick reply to this message  
Join Date: Dec 2007
Posts: 236
Reputation: TheBeast32 is on a distinguished road 
Solved Threads: 6
TheBeast32's Avatar
TheBeast32 TheBeast32 is offline Offline
Posting Whiz in Training

Re: Segmentation fault

 
0
  #3
Jul 21st, 2009
Thanks. I had to do data = realloc(data, ++datalen * sizeof(char)). I forgot the "data = ". I just looked it up in my little c reference book.

void* realloc(void* p, size_t size);
Returns pointer to newly-allocated space for an object of size size, initialised, to
minimum of old and new sizes, to existing contents of p (if non-null), or NULL on
error. On success, old object deallocated, otherwise unchanged.

Forgot it returns a pointer :/. I also got rid of the original calloc. I'll do error checking on realloc also. I didn't want to use a static buffer because I don't know how much data the user will enter. I could just ask for the amount of bytes I guess. I thought about leaving room for a null character at the end, but I'm going to be sending it to an smtp server, so does it matter?
Last edited by TheBeast32; Jul 21st, 2009 at 3:53 pm.
"Always program as if the person who will be maintaining your program is a violent psychopath that knows where you live."
--Martin Golding
Reply With Quote Quick reply to this message  
Join Date: Jun 2009
Posts: 830
Reputation: wildgoose is a name known to all wildgoose is a name known to all wildgoose is a name known to all wildgoose is a name known to all wildgoose is a name known to all wildgoose is a name known to all 
Solved Threads: 94
wildgoose's Avatar
wildgoose wildgoose is offline Offline
Practically a Posting Shark

Re: Segmentation fault

 
0
  #4
Jul 21st, 2009
Fair enough.
When I have data that grows with unknown maximum length I tend to track the memory usage and grow (realloc) when I reach the buffer size. Kind of what realloc does but more like growth spurts of 256 or more bytes. Not one at a time (though it appears your memory system is probably growing around 16 bytes at a time, since it did a memory exchange on your 13th realloc).
Last edited by wildgoose; Jul 21st, 2009 at 3:53 pm. Reason: typo
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC