Solved

struct definition error

Posted on 2008-10-30
28
278 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 

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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

717 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