LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Link Error 'Multiply Define Symbol'

Hi,

I will illustrate my problem with a smiple example:

My project has the following files:

file1.c
#include file3.h

file2.c
#include file3.h

file3.h
#ifndef _file3
#define _file3

char a[4]; //this one causes no error
char b[]="Hello"; //this one causes the error

#endif

Can anybody explain why I'm getting the link error

Thanks
0 Kudos
Message 1 of 9
(4,304 Views)
You have two choices:
1. Declare the variable in the .h file and initialize it in one .c file, not in the .h file. If you just declare a varible in a .h (but don't initialize it in the .h), you can include that .h in as many files as you would like. But you should initialize it (assign an initial value to it) in only one .c file, not in the .h file.
2. Declare the variable to be static, then it will get initialized only once.
e.g.
static char b[]="Hello";
0 Kudos
Message 2 of 9
(4,304 Views)
Hi Al and Thanks,

I don't understand why I should declare it as static. What is the advantage/significance of that.

What I ended up donig was declare it (not static) in one file (file1.c) and as external in the other.

Another question:
I declare char *msg=NULL;

then I initialize it msg="this is my message";
It wroks fine but I'm wondering how is the memory allocated for the string. Don't I need to use malloc?

Is it safe to use it the way I described?

Thanks
Rafi
0 Kudos
Message 3 of 9
(4,304 Views)
Using static initializes the variable only once. That's the benefit for your application as a global. In other uses, static allows a variable to retain its value even after the function ends in which it was declared. Using the variable as extern in your other .c files is fine for a single variable, but it gets to be more of a pain if you have multiple variables. That's where declaring it in a .h file that everybody can #include, but initializing it in only one .c file, is a better choice.
You do need to malloc to allocate space for msg. Depending on what the compiler put after msg, if you don't use malloc it may work sometimes or it may work in debug but not in release mode, etc. But you should malloc to allocate space for any string, structure, a
rray, etc., to which you declared a pointer.
0 Kudos
Message 4 of 9
(4,304 Views)
Thanks Al,

I noted your remarks and experimented with them. It looks fine!

Back to my other question regarding the memory allocation.

As a reminder: I declared in a local subroutine
char *Title=NULL;

Then, throughout my procedure I set Title to differnt values:
Title = "first message";
------
------
Title = "Second message";

I do it throught my program and never had any problem with it (I use CVI 7.0). I compile my project in release mode and still, no problem with these messages.

Can there be any explenation why it is working?

From you answere it is indicated that memory must be allocated. If I'll have to do it I will choose declaring a fix buffer like
char Title[256];
a
nd then just use it in a form-
strcpy(Title, "this is my message");

If I must do that it means modifying my program in hundreds places..... I really like to be sure I must do it. (this is why I asked your assistance in understanding how it workded)

Thank you
Rafi
0 Kudos
Message 5 of 9
(4,304 Views)
In message <50650000000500000093DF0100-1079395200000@exchange.ni.com>,
Rafi2003 writes
>Thanks Al,
>
>I noted your remarks and experimented with them. It looks fine!
>
>Back to my other question regarding the memory allocation.
>
>As a reminder: I declared in a local subroutine
> char *Title=NULL;
>
>Then, throughout my procedure I set Title to differnt values:
> Title = "first message";
> ------
> ------
> Title = "Second message";
>
>I do it throught my program and never had any problem with it (I use
>CVI 7.0). I compile my project in release mode and still, no problem
>with these messages.
>
>Can there be any explenation why it is working?
>
>From you answere it is indicated that me
mory must be allocated. If
>I'll have to do it I will choose declaring a fix buffer like
> char Title[256];
>and then just use it in a form-
> strcpy(Title, "this is my message");
>
>If I must do that it means modifying my program in hundreds
>places..... I really like to be sure I must do it. (this is why I
>asked your assistance in understanding how it workded)
>
>Thank you
>Rafi

The examples you show should be OK. C compilers must allocate memory for
constants such as "this is my message" and your variable, Title, is able
to store addresses of such constants. No additional memory allocation is
required.

However, this is only safe if your programme only ever points to
constants. Strings generated at run time will not have memory allocated.

In the following example the compiler will not allocate (or cause to be
allocated) memory for the string that results from sprintf().

char *Title=NULL;
int i=25;

sprintf (Title , "%d" , i );

Another less obvious bad example;


char *Title1 = "String 1";
char *Title2 = "String2";

strcat (Title1, Title2);

Most questions of this type (I.E. relating to ANSI C) have been answered
here;

http://www.eskimo.com/~scs

--
Regards,

John Cameron.
Type softly, read gently.
0 Kudos
Message 6 of 9
(4,304 Views)
I'm sorry, but you need to allocate memory for the string. There are several ways to do this.
1. Declare it as a fixed length string:
char title[256];
2. Declaring and initializing it in one statement:
char title[]="first message";
3. Declaring a pointer, then malloc'ing some space for it:
char *title;
...
title=malloc(256); // or whatever size you need.
The compiler decides how to allocate memory for variables. It can put variables back-to-back. If one variable overruns another variable's memory space, it's only noticed at run-time if both variables are used at the same time. It sounds like you're getting "lucky" like this.
Local variables in functions are, by default, automatic: they get automatically created when the fu
nction is called, then automatically released when the function ends. When a variable is released, its memory space may be reused by another variable in another function.
Sorry, but you're only asking for trouble if you don't allocate memory for the string. You may run fine for a while, then make a change apparently unrelated to the string, and strart scratching your head while the program crashes. It's just a required statndard practise in C to allocate memory.
0 Kudos
Message 7 of 9
(4,304 Views)
John:
Good answer!
I didn't catch what Rafi was doing with string constants: he's not updating the value of the string, but he's updating the pointer, changing it to point to a new string constant.
Thanks for the refresher!
0 Kudos
Message 8 of 9
(4,304 Views)
John's answer is correct. This answer is not correct in the limited application that Rafi shows: using only string constants, the compiler allocates space for the constants, so you don't need to malloc, etc. If you're only using string constants, you can declare a pointer and update the pointer to point to different string constants as Rafi shows. He's not updating the string value: He's changing the value of a pointer to point to a string constant.
Thanks John!
0 Kudos
Message 9 of 9
(4,304 Views)