473,382 Members | 1,362 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,382 software developers and data experts.

malloc array of structs + a little more

I'm having a problem with my array of structs and segmentation faults. I have this struct that represents one line of a source file:
Expand|Select|Wrap|Line Numbers
  1. struct threeTokens {
  2. int lineNumber;
  3. char* cmd;
  4. char* param;
  5. }; line;
This is the code that tries to fill the array of structs, which is a global variable called program:
Expand|Select|Wrap|Line Numbers
  1. program = malloc(numLines * sizeof(line));
  2.         while(NULL != fgets(buffer, SIZE, fp)){
  3.                 tokenPtr = strtok(buffer," ,\n");
  4.                 while(NULL != tokenPtr){
  5.                         switch(count){
  6.                         case 0: program[curLine].lineNumber = atoi(tokenPtr);
  7.                                 paramIndex += strlen(tokenPtr);
  8.                                 break;
  9.                         case 1: program[curLine].cmd = (char*)malloc(strlen(tokenPtr) * sizeof(char));
  10.                                 strcpy(program[curLine].cmd, tokenPtr);
  11.                                 paramIndex += strlen(tokenPtr);
  12.                                 break;
  13.                         default: paramLength += strlen(tokenPtr); break;
  14.                         }
  15.  
  16.                         program[curLine].param = (char*)malloc(paramLength * sizeof(char));
  17.                         for(i = 0; i < paramLength; i++){
  18.                                 program[curLine].param[i] = buffer[paramIndex + i];
  19.                         }
  20.                         tokenPtr = strtok(NULL, " \n");
  21.                 }
  22.                 curLine++;
  23.         }/*End While of buffer*/
When I try:
Expand|Select|Wrap|Line Numbers
  1. for(i = 0; i < numLines; i++){
  2.         printf("%d\t%s\t%s\n",program[i].lineNumber, program[i].cmd, program[i].param);
  3. }
I get:
Expand|Select|Wrap|Line Numbers
  1. 0       (null)
  2. 0       (null)
  3. 0       (null)
  4. 0       (null)
  5. 0       (null)
This results in a segmentation fault later on in my code which I'm sure is from me trying to access some null data. Any ideas?
Dec 7 '09 #1
8 3186
weaknessforcats
9,208 Expert Mod 8TB
Afyer you allocate the threeToken array, there are pointers (cmd and param) that are allocated but contain no address.

You need to allocate the memory those pointers point at.
Dec 7 '09 #2
Isn't that what I do within my switch statement? I malloc the memory and then copy the token into the newly allocated memory, right?
Dec 7 '09 #3
weaknessforcats
9,208 Expert Mod 8TB
strcpy(program[curLine].cmd, tokenPtr);
Where have you allocated program[curLine].cmd?

strcpy will copy from tokenPtr to program[curLine].cmd until it finds a \0.

You do not own the address in program[curLine].cmd since you never allocated it and that's where your seg error comes from.

You need to allocate strlen(tokenPtr) +1 and put that address in program[curLine].cmd before you strcpy.
Dec 7 '09 #4
One line above that I have:
program[curLine].cmd = (char*)malloc(strlen(tokenPtr) * sizeof(char));
I may need a '+1' but that doesn't explain why the entire string at program[curLine].cmd is null. At least I don't think, maybe I'm still missing what you're trying to say. But it's my understanding that line allocates the memory I need to copy tokenPtr into cmd.
Dec 7 '09 #5
Anyone else? This is very frustrating :(
Dec 7 '09 #6
newb16
687 512MB
Did you try it with '+1' ? Anyway, without reproducible example we can't help you much - you can try to step it through in debugger and see where the string that is supposed to be there corrupts, or put debug prints there for, e.g., program[0].cmd withing the loop to detect when it corrupts.
Dec 7 '09 #7
Banfa
9,065 Expert Mod 8TB
What I see is that the calculation of the token size at lines 9 and 13 using sizeof both omit to add 1 (+1) to take account of the NULL terminator so your allocated buffers are too small.

You are doing something strange with program[curLine].param in that you don't treat it like program[curLine].cmd and just allocate and copy it. I am guessing that you are string to copy everything after the first 2 tokens into it but you actually allocate and repeated copy to it causing multiple memory leaks and on cases 0 and 1through the loop quite possibly having a paramLength == 0 therefore causing invalid memory accesses by dereferencing the NULL pointer.

And finally the 2 lines that call strtok 3 and 20 use different separators which seems unlike to be correct and both include the \n character which certainly isn't correct since fgets reads a single line from the file there can be no more than a single \n of the line read. When parsing a line it is best to parse in a whitespace agnostic fashion and then strip leading and trailing white spaces from the tokens before storing them.


All the logic errors and possibilities for undefined behaviour in this code seem more than enough to me to result in the output you have.
Dec 7 '09 #8
RRick
463 Expert 256MB
I'll throw my 2 cents in and notice that count in the switch statement is never incremented. Each time you loop through you will do the same thing over and over (I assume count is initialized to 0) until you run out of tokens from strtok.

You are also doing something "weird" with the buffer by maintaining an offset paramIndex that you keep increasing. Finally, paramLength is not set until the default case, and who knows what is being copied.


What I notice in the code is that you are fighting against what is being returned by strtok. That might explain the paramIndex value. The simplest solution is to have strtok do the work for you and you control this with the delimiters passed to strtok. When strtok finds what you need, you simply copy the data from tokenPtr to your structure. There is no need to maintain an index into the buffer.
Dec 8 '09 #9

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

Similar topics

36
by: Bhalchandra Thatte | last post by:
I am allocating a block of memory using malloc. I want to use it to store a "header" structure followed by structs in my application. How to calculate the alignment without making any assumption...
29
by: David Hill | last post by:
Is there a difference between: /* code 1 */ struct sample test; test = malloc(sizeof(struct sample)); memset(&test, 0, sizeof(test)); /* code 2 */ struct sample test; test = calloc(1,...
15
by: Lars Tackmann | last post by:
Hi, i have the following type and struct defined typedef struct hNode { unsigned char name; unsigned long hVal; struct hNode *next; } HashNode; what i want, is to ensure that when doing:
10
by: Ian Todd | last post by:
Hi, I am trying to read in a list of data from a file. Each line has a string in its first column. This is what i want to read. I could start by saying char to read in 1000 lines to the array( i...
5
by: Grant Austin | last post by:
What would be the correct syntax for setting up a dynamic array of structs? Suppose you have a struct declared: struct relation { FILE * binFile; unsigned int numAttrs; struct attrList *...
1
by: mrhicks | last post by:
Hello all, I need some advice/help on a particular problem I am having. I have a basic struct called "indv_rpt_rply" that holds information for a particular device in our system which I will...
5
by: Bidule | last post by:
Hi, I'm trying to sort structs defined as follows: struct combinationRec { float score; char* name; }; The number of structs and the length of the "name" field are not known
1
by: Kevin | last post by:
Hi all, I clearly have an issue with some pointers, structures, and memory allocation. Its probably pritty basic, but I'm a little stuck. Any help would be greatly appreciated. I'd like...
2
by: hal | last post by:
Hi, I'm trying to make an array of pointers to 'TwoCounts' structs, where the size of the array is arraySize. Right now I'm just mallocing enough space for all the pointers to the structs, and...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.