0

I am using the following code to split a char array in C:

 char line[100]; int number_of_gga_parsed = 0; int gga_blocks_allocated; gga_sentence *ggas_parsed; gsa_sentence gsa; gsv_sentence gsv; ggas_parsed = malloc(10*sizeof(gga_sentence)); gga_blocks_allocated = 10; if(ggas_parsed == NULL){ printf("error allocating memory, system exiting.\n"); exit(EXIT_FAILURE); } while(fscanf(stream, "%s", line)!= EOF){ strcpy((ggas_parsed + number_of_gga_parsed)->untouched_sentence, line); initiate_gga_values((ggas_parsed + number_of_gga_parsed),(ggas_parsed + number_of_gga_parsed)->untouched_sentence); 

}

initiate_gga_values function:

void initiate_gga_values(gga_sentence* gga_ptr, const char* sentence){ char *temp_sentence; char *token; int token_no = 0; /*Copy the gga_sentence into the temp_sentence char array*/ strcpy(temp_sentence, sentence); token = strsep (temp_sentence,","); while (token != NULL) { switch(token_no){ case 0: gga_ptr->sentence_id = token; break; case 1: /*atoi converts a string to an int, well a c string anyways so a char* */ gga_ptr->time_stamp = atoi(token); break; case 2: /*strtod coverts a string to a double, well a c string anyways so a char* */ gga_ptr->latitude = strtod(token, NULL); break; case 3: gga_ptr->north_south_id = (char)token; break; case 4: gga_ptr->longitude = strtod(token, NULL); break; case 5: gga_ptr->east_west_id = (char)token; break; case 6: gga_ptr->quality = atoi(token); break; case 7: gga_ptr->no_of_satellites = atoi(token); break; case 8: gga_ptr->horizontal_dillution = strtod(token, NULL); break; case 9: gga_ptr->altitude = strtod(token, NULL); break; case 10: gga_ptr->altitude_units = (char)token; break; case 11: gga_ptr->geodial_seperation = strtod(token, NULL); break; case 12: gga_ptr->geodial_seperation_units = (char)token; break; case 13: gga_ptr->age_of_data_in_seconds = strtod(token, NULL); break; case 14: gga_ptr->checksum = token; break; } token_no++; token = strsep (temp_sentence, ","); } } 

The char array consists of this information:

$GPGGA,151019.000,5225.9627,N,00401.1624,W,1,09,1.0,38.9,M,51.1,M,,0000*72 

but when the code in run on the above, i get a segmentation fault:

Segmentation fault (core dumped) 

gga struct:

typedef struct gga_sentence{ char untouched_sentence[100]; gsa_sentence gsa; char *sentence_id; int time_stamp; double latitude; char north_south_id; double longitude; char east_west_id; int quality; int no_of_satellites; double horizontal_dillution; double altitude; char altitude_units; double geodial_seperation; char geodial_seperation_units; double age_of_data_in_seconds; char *checksum; }gga_sentence; 

The segmentation fault happens before the function initiate_gga_values function completes, or even starts really. This means i assume there is a problem with the mallocing of gga_sentences but i cannot see where!

This is the first time i am using strsep, so no doubt i am doing something very wrong.

gdb error message:

Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7de4103 in _dl_lookup_symbol_x (undef_name=0x4004d8 "strlen", undef_map=0x7ffff7ffe268, ref=ref@entry=0x7fffffffdbb8, symbol_scope=0x302e312c362e312c, version=0x7ffff7ff9a08, type_class=type_class@entry=1, flags=1, skip_map=skip_map@entry=0x0) at dl-lookup.c:733 733 dl-lookup.c: No such file or directory. 

Cheers, Chris.

7
  • What is gga_ptr? How are you initializing it? Commented Mar 10, 2014 at 19:09
  • sorry i thought i added that! ill add it now! Commented Mar 10, 2014 at 19:09
  • to me ` strcpy((ggas_parsed + number_of_gga_parsed)->untouched_sentence, line);` looks dubious. What are you trying here using number_of_gga_parsed ? Commented Mar 10, 2014 at 19:19
  • @brokenfoot the idea is, because you dont know the number of gga_sentences in the file i keep track of how many ive read, then use pointer addition to locate where i want it stored so initially number_of_gga_parsed = 0 so (ggas_parsed + number_of_gga_parsed) should point to index 0 in the mallocd memory, when number_of_gga_parsed = 10, i want the 10th index in the malloc'd memory. Commented Mar 10, 2014 at 19:22
  • Just for precaution, check for NULL pointer while accessing gga_ptr->sentence_id = token;, put a if(NULL==gga_ptr) {//handle the error} Commented Mar 10, 2014 at 19:30

3 Answers 3

3
char *temp_sentence; char *token; int token_no = 0; /*Copy the gga_sentence into the temp_sentence char array*/ strcpy(temp_sentence, sentence); 

You aren't allocating any memory for temp_sentence to hold the copied string

Sign up to request clarification or add additional context in comments.

2 Comments

i added this line: temp_sentence = malloc(sizeof(sentence)); just abov e the strcpy line and still a seg fault :/
sizeof(sentence) is the size of a pointer, maybe 8 bytes. You'll need strlen(sentence) + 1 here. (The extra byte holds the null character at the end.) Or you could use temp_sentence = strdup(sentence).
0
token = strsep (&temp_sentence,","); 

strsep takes char** as first argument.

6 Comments

is your temp_sentence long enough? have you tried making it bigger?
i changed it to a char* and still the same problem.
@chrisedwards try with char[1000] if it holds
on further debugging, ive noticed that the segfault happens before strsep is reached, i guess its a memory allocation error.
@chrisedwards my guess is temp_sentence can't hold your const char*
|
0

You are copying sentence to uninitialised memory:

char *temp_sentence; /* ... */ strcpy(temp_sentence, sentence); 

temp_sentence is an uninitialised pointer that points to some random place, but not to any extra memory. To fix this, you could allocate a certain amount of chars on the stack, say:

char temp_sentence[100]; strncpy(temp_sentence, sentence, sizeof(temp_sentence) - 1); 

This might cut your string short. An alternative is to allocate a duplicate of the input string on the heap:

char *temp_sentence = strdup(sentence); 

In that case you must free the allocated memory with free(temp_sentence) before returning from the function. In either case, you'll need a second pointer that you can pass to strsep:

char *ptr = temp_sentence; 

This pointer needs to be modifiable, so you can't use an array. If the temporary string is allocated with strdup you need to retain the original pointer so you can free your memory.

Edit: As already noted by Arjun Sreedharan, you should pass a pointer to a pointer to char as a first parameter to strsep. That way, the pointer gets updated and refers to the rest of the string that hasn't been parsed yet.

A mismatch of pointer types should really give a warning message. Have you enabled warnings?

Anyway, here's a short working example of what you want to do, but without the actual parsing:

#include <stdlib.h> #include <stdio.h> #include <string.h> int main() { const char* sentence = "$GPGGA,151019.000,5225.9627,N," "00401.1624,W,1,09,1.0,38.9,M," "51.1,M,,0000*72"; char *tmp = strdup(sentence); // modifiable copy char *p = tmp; // pointer into copy for strsep char *token; int token_no = 0; token = strsep(&p, ","); while (token != NULL) { printf("%d: '%s'\n", token_no, token); token_no++; token = strsep(&p, ","); } free(tmp); // release ressources of copy return 0; } 

3 Comments

ive added what you said, i still get a seg fault.
The crash happens somewhere in the system functions. Get a traceback with where and look in which of your functions the crash happens. Be sure to compile with -g so that you get symbol names and line numbers. Anyway, I reckon that your crashes are a combination of everything other posters and I have mentioned. I've added a working framework from which you can start.
The problem is to do with the malloc of the gga_sentence memory, i have removed line after line and it throws an seg fault when i use that memory. ill look into the problem now.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.