473,406 Members | 2,377 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

C pointer issues... Segmentation fault!

Howdy!

I'm mega confused with all this pointer malarky in C and it's resulting in an ever annoying segmentation fault which just won't go away!

Essentially the program I am building has a Get() function which reads 1 record of data from a file, another function adds this record (or struct) to a data structure, then the Get function reads and returns the next record.

A record consists of a surname, address (with spaces), and postcode (with spaces), however the file format is:
line 1. surname, firstname (although I only need surname)
line 2. address
line 3. postcode and so on.

My code succesfully reads the first 2 records (as I make it print it to screen to check), and then I am presented with a "error while dumping state <probably corrupted stack>"

The code is as follows:
Expand|Select|Wrap|Line Numbers
  1. // read surname up until a comma //
  2.         memset(namebuf, 0, MAXLINESIZE);
  3.     printf("Name : ");
  4.     i = 0;
  5.     ch = fgetc(fd);
  6.     while(ch != ',' && ch != EOF) {
  7.     namebuf[i] = tolower(ch);
  8.     ch = fgetc(fd);
  9.         i++; }
  10.  
  11.     test.surname = malloc(MAXLINESIZE);
  12.     strcpy(test.surname, namebuf);
  13.     printf("%s", test.surname); 
  14.     putchar('\n');
  15.  
  16. // get the first name, and don't do anything with it //
  17.         memset(namebuf, 0, MAXLINESIZE);
  18.     firstname = malloc(MAXLINESIZE);
  19.     strcpy(firstname, fgets((namebuf +1), MAXLINESIZE, fd));
  20.  
  21.     // get address //
  22.     printf("Address : ");
  23.     test.full_address = malloc(MAXLINESIZE);
  24.     strcpy (test.full_address, fgets((addressbuf +1), MAXLINESIZE, fd));
  25.     printf("%s", test.full_address);    
  26.  
  27.     // get postcode //
  28.     //memset(buf, '\0', MAXLINESIZE);
  29.     printf("Postcode : ");
  30.     test.postcode = malloc(MAXLINESIZE);
  31.     strcpy (test.postcode, fgets((postcodebuf +1), MAXLINESIZE, fd));
  32.     printf("%s", test.postcode);
  33.     putchar('\n'); 

Any ideas? I've been stumped for days, and I'm very new to the whole malloc concept...!

Any help would be vastly appreciated!
Oct 31 '07 #1
10 2029
Expand|Select|Wrap|Line Numbers
  1.     printf("Postcode : ");
  2.     test.postcode = malloc(MAXLINESIZE);
  3.     strcpy (test.postcode, fgets((postcodebuf +1), MAXLINESIZE, fd));
  4.     printf("%s", test.postcode);
  5.     putchar('\n'); 
  6.  
Im not sure, perhaps postcodebuf has not been allocated before using it
Oct 31 '07 #2
I used:

char postcodebuf[MAXLINESIZE];
Oct 31 '07 #3
mattmao
121 100+
Hi.

Just one thing: where is your struct test ? I couldn't find it inside your example code.

From my personal experience in studying linked list, use a pointer to struct testClass would be a better choice, such like:

Expand|Select|Wrap|Line Numbers
  1. struct testClass
  2. {
  3.   int number;
  4.   char address[SIZE];
  5.   struct testClass *next;
  6. }
  7. typedef struct testClass test;

In your code, you can use this to allocate memory space:
Expand|Select|Wrap|Line Numbers
  1. test *a= (test *) malloc(sizeof(test));
Then access the content of this struct like this:
Expand|Select|Wrap|Line Numbers
  1. a->number = 100;
  2. strcpy(a->address, from);
  3. a->next = b;
  4.  
Most of the references books I read recommanded this way.
Oct 31 '07 #4
Ok - here's the full code:

typedef struct entry {
char *surname;
char *postcode;
char *full_address;
} Entry;

/* get returns next file entry, or NULL if end of file*/
Entry *get(FILE *fd)
{
int i;
char addressbuf[MAXLINESIZE];
char postcodebuf[MAXLINESIZE];
char namebuf[MAXLINESIZE];
char ch;
char *firstname;
Entry test;

// get surname //
memset(namebuf, '\0', MAXLINESIZE -1);
printf("Name : ");
i = 0;
ch = fgetc(fd);
while(ch != ',' && ch != EOF) {
namebuf[i] = tolower(ch);
ch = fgetc(fd);
i++; }

test.surname = malloc(MAXLINESIZE);
strcpy(test.surname, namebuf);
printf("%s", test.surname);
putchar('\n');

memset(namebuf, '\0', MAXLINESIZE);
firstname = malloc(MAXLINESIZE);
strcpy(firstname, fgets((namebuf +1), MAXLINESIZE, fd));

printf("Address : ");
test.full_address = (char *)malloc(strlen(addressbuf)+1);
test.full_address = (fgets(addressbuf, MAXLINESIZE, fd));
strcpy(test.full_address, addressbuf);
printf("%s", test.full_address);

printf("Postcode : ");
test.postcode = (char *)malloc(strlen(postcodebuf)+1);
test.postcode =(fgets(postcodebuf, MAXLINESIZE, fd));
strcpy(test.postcode, postcodebuf);

printf("%s", test.postcode);
}
Oct 31 '07 #5
mattmao
121 100+
Hi.

Can you quote your code into CODE tags? Just for the ease to read...

And I don't quite get your idea of separately allocate memory space for each element of a struct variable. You use something like:
Expand|Select|Wrap|Line Numbers
  1. test.surname = malloc(MAXLINESIZE);
If you declared Entry test, then test.surname would be of type char *,
malloc() would return you a pointer of type void, so at least you've missed a cast:
Expand|Select|Wrap|Line Numbers
  1. test.surname = (char *) malloc(MAXLINESIZE);
And, I guess you've got this:
Expand|Select|Wrap|Line Numbers
  1. #define MAXLINESIZE 100
which means this:
Expand|Select|Wrap|Line Numbers
  1. test.surname = (char *) malloc(100);
You are asking for the malloc method to allocate you the memory space for 100.
This is not legal, I guess.
It should be:
Expand|Select|Wrap|Line Numbers
  1. char array[MAXLINESIZE];
  2. test.surname = (char *) malloc(sizeof(array[MAXLINESIZE]));



Still, why wouldn't you allocate a memory space set for one struct element in one go, as I mentioned before?

Sorry I must go for lesson now, can't check for the rest of your code.
Oct 31 '07 #6
RRick
463 Expert 256MB
Your problem lies in the sections of code that deal with address and postcode.

You are malloc'ing on the strlen of addressbuf and postcodebuf, but they don't contain anything. Strlen will not tell you big your buffer is, it will only tell you how large the string in the buffer is. When strlen finds the first '\000', it stops. In the case of postcodebuf (which is where your program blows up), strlen probably returns a length of 0. After that, you copy a bigger string into a smaller string.

A simple solution is to switch the malloc and fgets lines. This should fix the problem, but be sure to do for address and postcode
Expand|Select|Wrap|Line Numbers
  1.  
  2.     printf("Postcode : ");
  3.     test.postcode =(fgets(postcodebuf, MAXLINESIZE, fd));
  4.     test.postcode = (char *)malloc(strlen(postcodebuf)+1);
  5.     strcpy(test.postcode, postcodebuf);
  6.  
Also, the get routine needs to be cleaned up. You are using fgetc and fgets to get the values. Stick with one. Also, you use two different ways to malloc the buffers.
Oct 31 '07 #7
Howdy!

Thanks for your help there, I understand what you meant, and actually thought it would fix the problem... but it hasn't! :(

The reason I use two methods to read the file, is that I *only* need the surname of the first line, not the first name (it's discarded), thus I must read only up to the comma.

Now it still reads in only 2 records, then hits a segmentation fault. Code is now:

Expand|Select|Wrap|Line Numbers
  1. typedef struct entry { 
  2.     char *surname;
  3.     char *postcode;
  4.     char *full_address;
  5. } Entry;
  6.  
  7. Entry *me_get(FILE *fd)
  8. {
  9.     int i;
  10.     char addressbuf[MAXLINESIZE];
  11.     char postcodebuf[MAXLINESIZE];
  12.     char namebuf[MAXLINESIZE];
  13.     char fnamebuf[MAXLINESIZE];
  14.         char ch;
  15.     char *firstname;
  16.     Entry test;
  17.  
  18.     // get surname //
  19.     memset(namebuf, '\0', MAXLINESIZE -1);
  20.     printf("Name : ");
  21.     i = 0;
  22.     ch = fgetc(fd);
  23.     while(ch != ',' && ch != EOF) {
  24.     namebuf[i] = tolower(ch);
  25.     ch = fgetc(fd);
  26.     i++; }
  27.  
  28.     test.surname = (char *)malloc(strlen(namebuf)+ 1);
  29.     strcpy(test.surname, namebuf);
  30.     printf("%s", test.surname); 
  31.     putchar('\n');
  32.  
  33.     // get first name //
  34.     memset(fnamebuf, '\0', MAXLINESIZE);
  35.     fgets(fnamebuf, MAXLINESIZE, fd);
  36.     firstname = (char *)malloc(strlen(fnamebuf)+ 1);
  37.     strcpy(firstname, fnamebuf);
  38.  
  39.     // get address //
  40.     printf("Address : ");
  41.     fgets(addressbuf, MAXLINESIZE, fd);
  42.     test.full_address = (char *)malloc(strlen(addressbuf)+ 1);
  43.     strcpy(test.full_address, addressbuf);
  44.     printf("%s", test.full_address); 
  45.  
  46.     // get postcode //
  47.     printf("Postcode : ");
  48.     fgets(postcodebuf, MAXLINESIZE, fd);
  49.     test.postcode = (char *)malloc(strlen(postcodebuf)+ 1);
  50.     strcpy(test.postcode, postcodebuf);
  51.     printf("%s", test.postcode);  
Nov 1 '07 #8
I think its time to let the code tell us where the error is. I.e.
Expand|Select|Wrap|Line Numbers
  1.  
  2. if( fgets( postcodebuf, MAXLINESIZE, fd ) == NULL )
  3. {
  4.    printf("Error at fgets\n");
  5.    exit(-1);
  6. }
  7. test.postcode = (char *)malloc(strlen(postcodebuf)+ 1);
  8. if( test.postcode == NULL )
  9. {
  10.    printf("Error at malloc\n");
  11.    exit(-1);
  12. }
  13. strncpy(test.postcode, postcodebuf,strlen(postcodebuf)+ 1);
  14. printf("%s", test.postcode); 
  15.  
  16.  
Nov 1 '07 #9
weaknessforcats
9,208 Expert Mod 8TB
Entry *me_get(FILE *fd)
{
int i;
char addressbuf[MAXLINESIZE];
char postcodebuf[MAXLINESIZE];
char namebuf[MAXLINESIZE];
char fnamebuf[MAXLINESIZE];
char ch;
char *firstname;
Entry test;
I can't see your entire function but I notice it returns an Entry*. I certainly hope it's not returning the address of test because that is a local variable which is destroyed when this function returns.

I suspect that's what you are doing as you are loading up the members of test.

If , in fact, that is what you are doing, then you will need to allocate test on the heap.
Nov 1 '07 #10
You are exactly correct - and I have now done this, and all is compiling well! I also fiddled a few other bits... Thank you all for your help!

Now I've gotta figure out how to stick this in a hash table! Eek!! I may be back!
Nov 1 '07 #11

Sign in to post your reply or Sign up for a free account.

Similar topics

1
by: sandwich_eater | last post by:
I get a segmentation fault in my program when calling a function "TestFn" that has been passed as a pointer into another function. The following excerpt should give enough information as to what I...
7
by: Marcus Jacobs | last post by:
Before I am flamed, I did search the FAQ for an answer to the question that I am about to post. Even with a search of the newsgroup archive, there are so many subjects about pointers I could search...
25
by: No Such Luck | last post by:
Hi all: Below are two pieces of code that basically perform the same task. Version A produces a segmentation fault, while version B works correctly. I understand why version B works correctly,...
12
by: Andreas Schmidt | last post by:
I am trying to understand the behavior of void pointers. Can someone explain to me why I get a segfault for the following program? #include <stdio.h> void* plusone(void* i){ int* arg =...
8
by: Ben | last post by:
Hi, I am having trouble debugging a segmentation fault...here's my data structure: typedef struct CELL *pCELL; /* Pointers to cells */ struct CELL { SYMBOL symbol; pCELL prev_in_block;...
3
by: madunix | last post by:
My Server is suffering bad lag (High Utlization) I am running on that server Oracle10g with apache_1.3.35/ php-4.4.2 Web visitors retrieve data from the web by php calls through oci cobnnection...
25
by: dis_is_eagle | last post by:
Hi.I have a question on the following statement. char* a="hello"; The question is where "hello" gets stored.Is it in some static area ,stack or heap.I have observed that attempting to modify...
15
by: Steven T. Hatton | last post by:
I found the example code below, listed in the book described here: http://cartan.cas.suffolk.edu/moin/OopDocbookWiki The result was a bit surprising. I guess it falls into the category of...
10
by: H.S. | last post by:
Hello, I have class in which I am allocating space for a double array in the constructor. I use the double array twice in one of the methods and then delete that array in the class's destructor....
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.