Solved

struct definition error

Posted on 2008-10-30
28
272 Views
Last Modified: 2012-05-05
Hello group,

Following code works fine in a different module but using it in my current code casues an error message as following:

    error: conflicting types for 'first_item'

Why is there a conflict when struct has the same type?!

Regards.


//
 

struct account

{

   char *group_id;    

   char *id;          

   char *domain;      

   struct account* next;

};
 

//following lines are used out of main

struct account *first_item;

struct account *current_item;

struct account *new_item;
 

first_item = (struct account *)malloc(sizeof(struct account));  <<<< causes error here

current_item = first_item;

Open in new window

0
Comment
Question by:akohan
  • 11
  • 10
  • 4
  • +2
28 Comments
 
LVL 23

Expert Comment

by:Mysidia
ID: 22847604
struct account *first_item;
^^^^^^^^^^^^^^^^^^^^
The reason this would show as conflicting types is most likely that you have declared  the global variable "first_item" somewhere else, also.

And the definition is different,  I.E.  either it is a different structure, or using a different instance of the definition.

Make sure that it is a "struct account"  type in both places.
AND  the definition for "struct account"  itself  exists only in one place   (no duplicate definitions,  or multiple inclusions of the definition)



0
 
LVL 24

Expert Comment

by:fridom
ID: 22847976
The code as shown is correct,  but not very idiomatic C
Write first_item = malloc(sizeof(*first_item));
Much cleaner

Regards
Friedrich
0
 

Author Comment

by:akohan
ID: 22848097

This is weird! since I have only two lines as following. Also I changed it as Fridom has suggested but still I'm getting the error already was mentioned above!!!

struct account *first_item;                        //1 here
struct account *current_item;
struct account *new_item;

first_item = (struct account *)malloc(sizeof(struct account)); // and the other one here

Any idea?!

Regards.



0
 
LVL 84

Expert Comment

by:ozo
ID: 22848129
is the executable code
first_item = (struct account *)malloc(sizeof(struct account));
inside a a function?
0
 

Author Comment

by:akohan
ID: 22848135


No, it is defined as global out of main() function.
0
 
LVL 84

Expert Comment

by:ozo
ID: 22848147
you can't put
first_item = (struct account *)malloc(sizeof(struct account));
outside of a function
0
 
LVL 84

Expert Comment

by:ozo
ID: 22848167
you can put

struct account static_first[1];
struct account *first_item = static_first;

outside a function, if that's what you are trying to do
0
 

Author Comment

by:akohan
ID: 22848199

I didn't know that but then I moved it into a function and worked! now I'm having problem with value of element of the struct. It has some values left over from  previous iteration:

current_item->group_id = malloc(strlen(s) + 1);
strcpy(current_item->group_id,  s);
printf("\ngroup id = %s", current_item->group_id);   /// it must show 2 but it shows   2"reshold"d"

How can I clean it before read operation?

Regards.


0
 
LVL 84

Expert Comment

by:ozo
ID: 22848211
is s null teminated?
0
 

Author Comment

by:akohan
ID: 22848216

struct elements are from char* type and I have not concatenated any null terminated character to them.

0
 

Author Comment

by:akohan
ID: 22848220

Doesn't strcpy adds it automatically to it?
0
 
LVL 84

Expert Comment

by:ozo
ID: 22848231
strcpy(current_item->group_id,  s) does not add anything to s
If you only want to print the first character of current_item->group_id
you can do
printf("\ngroup id = %.1s", current_item->group_id);
0
 

Author Comment

by:akohan
ID: 22848236

Right but I need to filter it before storing it into the field. The reason I'm using char* is because I don't know what length of data I will be reading.
0
 
LVL 84

Expert Comment

by:ozo
ID: 22848252
If you don't know what length of data you will be reading, how do you know //// it must show 2 ?
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:akohan
ID: 22848288

I'm reading a generated csv file which I can see it. in first row group id is 2 but in next one is 15 or ...
what I meant from not knowing it is because a different program generates it but yes I can see what is inside the file.

In this case I have:
"group id", "name", "id", "system", "domain", "threshold"
 "2", "some data", .........................

it seems the last header and 2 are mixed that is why I need to clean the location where pointer is pointing before reading the data.

Regards,
ak




0
 
LVL 84

Expert Comment

by:ozo
ID: 22848308
Do you want to scan s for a comma and replace it with a null?
0
 

Author Comment

by:akohan
ID: 22848321

I'm using a CSV library which scans the csv file it has a callback function as in snippet. As you see argument s points to the data where each data is a field in the csv file. I guess it doen't clean so I need to find out how it would be possible to clean it before reading a next field.

Any idea?

Thanks.



void get_fields(void *s, size_t len, void *data)

{

   //my code is in this function and *s always points to a data field 

   //all I need is to clean this before reading.

}

Open in new window

0
 

Author Comment

by:akohan
ID: 22848323

the library called libcsv which I found on sourceforge.net

0
 
LVL 84

Expert Comment

by:ozo
ID: 22848346
if len is the length of the field, then s[len]=0 should null terminate it
0
 
LVL 23

Expert Comment

by:Mysidia
ID: 22849522
You need to place a null terminator on the string before using any of the str* functions,  printf %s  argument.  In fact, the C libraries assume the string is null terminated, that's how they determine the length of your string..

If strcpy never encountered a zero byte,  it could wind up copying a very large "string" (data from your program's memory outside the expected string)....


In your callback,  you should make the copy of the string have a specified length.

i.e. if the length is 'len' bytes, then, for example...

current_item->group_id = (char*) malloc(strlen(s) + 1);
memcpy(current_item->group_id, s, len);
current_item->group_id[len] = '\0';

printf("\ngroup id = %s", current_item->group_id);   /// it must show 2 but it shows   2"reshold"d"


Unlike  strcpy(),   memcpy()   does not require the string you are copying from to be nul-terminated.



0
 
LVL 23

Expert Comment

by:Mysidia
ID: 22849532
Sorry, you must also  replace strlen(s)   with the known length.

strlen() uses null terminators also.
0
 
LVL 84

Expert Comment

by:ozo
ID: 22852787
> if len is the length of the field, then s[len]=0 should null terminate it
Assuming s has space for an extra null at the end of the field
0
 

Author Comment

by:akohan
ID: 22853191


 Of course, since s is a void* compiler doesn't let me to do s[len] = '\0' but then I used
current_item->group_id[len] =  '\0';

I was expecting current_item->group_id[len+1] =  '\0'; to work but didn't !

so then it seems ok with current_item->group_id[len] =  '\0';

I also noticed have a solution from Mysidia (thanks!). As he has mentioned it looks I have to use memcpy rather than strcpy. I try that and will get back to you guys.

One question I'm having is that is current method in above I have used safe?!

Regards,
ak



0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22853210
>> As he has mentioned it looks I have to use memcpy rather than strcpy.

For strings, it's better to use strncpy (notice the extra n) if the string is not null terminated and its length is known :

        http://www.cplusplus.com/reference/clibrary/cstring/strncpy.html
0
 
LVL 84

Expert Comment

by:ozo
ID: 22853234
strlen
strcpy
printf("%s"
are not safe unless you have a null terminated string
0
 

Author Comment

by:akohan
ID: 22853347

In this case, I don't have null terminated string since if I read the first value as "abcdefg" when I read the very next value (assume it is "test") then
s = "testefg"

as you see still it has left over characters from its previous iteration.

so just to summerize what is discussed here I must do this using strncpy. Right?
then may I ask what will be effect of memcpy() function?

Regards.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22854099
memcpy is a memory copy function. strncpy is a string copy function. With both, you specify the amount of data to be copied, but strncpy also stops if it finds a '\0'. So, it's preferable to use it for strings.
0
 
LVL 23

Accepted Solution

by:
Mysidia earned 350 total points
ID: 22854783
It's generally not considered safe to write a trailing \0  to a string provided you by a callback method, unless the API says there is extra space provided for you to do it,  which I don't believe is the case here..
If the library you are using provides extra padding, why didn't they make it NUL padding,  so it would be zero-terminated?

Actually, in libcsv3  this should be possible:  use the CSV_APPEND_NULL parser  option,  when you are initializing your parser with csv_init().



I would suggest modifying your copy of the string, but not the original provided to you by libcsv.

If  the libcsv CSV_APPEND_NULL   option   is available to you, then this is even better,  as it eliminates extra work  massaging the strings to fit your needs.


0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now