| | |
Segmentation fault
![]() |
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.
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.
. 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. C Syntax (Toggle Plain Text)
char *data, ch; char newline; unsigned int datalen; data = (char*)calloc(1, sizeof(char)); newline = 1; datalen = 0; while (1) { ch = fgetc(stdin); realloc(data, ++datalen * sizeof(char)); *(data + datalen - 1) = ch; if (newline) { if (ch == '.') { realloc(data, ++datalen * sizeof(char)); *(data + datalen - 1) = '\n'; break; } else if (ch != '\n') { newline = 0; } } else { if (ch == '\n') { newline = 1; } } }
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
--Martin Golding
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...
...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?
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...
C Syntax (Toggle Plain Text)
data = realloc( data, +datalen *sizeof(char) );
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.
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?
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
--Martin Golding
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).
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
![]() |
Similar Threads
- segmentation fault (C)
- Access Violation (Segmentation Fault) + atol (C++)
- unix/C++ segmentation fault (C++)
- what is the best way to track segmentation fault errors (C++)
Other Threads in the C Forum
- Previous Thread: Reading Line By Line question
- Next Thread: programming with DLL's functions
| Thread Tools | Search this Thread |
* adobe api array arrays binarysearch calculate centimeter char cm convert copyanyfile copypdffile cprogramme createcopyoffile createprocess() csyntax directory dynamic feet fflush file floatingpointvalidation fork forloop frequency getlasterror getlogicaldrivestrin givemetehcodez global graphics gtkgcurlcompiling gtkwinlinux hacking hardware highest homework i/o ide inches incrementoperators intmain() iso km linked linkedlist linux linuxsegmentationfault list locate logical_drives loopinsideloop. match matrix microsoft motherboard mqqueue mysql oddnumber odf open opendocumentformat opensource openwebfoundation pattern pdf performance pointer posix power program programming pyramidusingturboccodes read recursion recv recvblocked repetition scanf scheduling segmentationfault send shape single socketprograming socketprogramming stack standard strchr string suggestions test unix urboc user variable voidmain() whythiscodecausesegmentationfault win32api windows.h





