(changed name of variable from original question to fit the actual code)
I'm new to C and I'm implementing a queue.
The error is with the static int head=0 variable. It's incremented by 1 each time dequeue() is called. The error seem to occur when the queue is dequeued and function get_person() is called. The head-variable is then as it seems getting a high random number, like 23423449. I have no idea where this comes from. However if I get rid of the "static" keyword so variable is declared as int head=0, it works fine. How come?
using a "global" variable in top of a included file: static int variable1=0
This clearly indicates, that you don't understand what the static keyword means on the global scope. In the global scope, outside of a function, static means, that the variable is visible to only the code within the compilation unit the variable has been defined in.
Now if you define a static variable in a header, each compilation unit that includes that header will have its own variable of that name. So your program is littered with many identically named variables each specific to the compilation unit it's in.
I think what you actually want is an non-static, extern declaration in the header, and exactly one compilation unit actually defining the variable.
I think you are overrunning your person array
One of the strcpy functions is going beyond the bounds of the buffers in the person object, and overwriting the head variable. I would guess the tail and nbr_elem are going too.
You should check that the number of characters you are copying does not exceed the buffer lengths, or use strncpy.
If you declare a global static variable in file A.c, it means this variable is only available within the scope of this A.c file. See : http://en.wikipedia.org/wiki/Static_variable
Since you haven't posted any code, and you are metioning using the same variable in a different file (e.g. B.c), it seems like it is invoking an undefined behavior, which explains the random number your program is printing.
If you wish to use the variable in a different .c file, you should not make it static.
You are calling strcpy without checking that the values you are trying to write will actually fit inside the allocated space inside the person struct.
What is most likely happening is you are writing beyond the allocated memory, and your strcpy is actually overwriting the value of head. strcpy will keep writing until it hits a null terminator ('\0').
If you were to run this in valgrind (a useful tool for finding this type of problem in large programs) it would probably tell you you have invalid writes occurring.
C assumes you know what you are doing, as long as you have access to the memory you can do with it as you please :)
Related
I'm working through K&R so pardon my mediocre understanding of C. I'm trying to store the values of argv as ints in an external array. So my first question is: is it possible to create an external array with size dependent on argc? Or is there any workaround other than just using an arbitrarily long array and hoping it all fits.
Second I was experimenting with using a pointer to an undefined integer array. I was able to increment the pointer a large number of times, both reading from (almost everything was zero) and writing to the pointed memory before I got a "Bus error: 10." Is there a reason that I was able to access so much memory before I got a bus error, or is that all just part of "undefined behavior?"
Here is the code that tested the undefined array.
#include <stdio.h>
int main(void);
int test();
int a[];
int main(void)
{
test();
}
int test()
{
extern int a[];
int *a0 = a;
printf("%d\n", *a0);
while (1) {
*a0 = 1;
a0++;
printf("%d\n", *a0);
}
return 0;
}
is it possible to create an external array with size dependent on argc?
Not really. You can allocate an array and store a pointer to it into a global storage segment, but it would be a pointer, not an array.
I was able to increment the pointer a large number of times, both reading from (almost everything was zero) and writing to the pointed memory before I got a "Bus error: 10."
The very first read or write outside the array is illegal. The fact that you do not get "Buss Error: 10." right away is an unfortunate coincidence, because the code may appear to work when it is actually incorrect.
is that all just part of "undefined behavior?"
Yes, this is undefined behavior.
Firstly, let's clarify a bit what extern does. In C, there's a thing called translation units. For now, imagine them as being just .c files. When you compile them, each .c file forms a translation unit and produces an object file (.o). The object files are then put together to create the final executable file by the linker. Sometimes you want to define (i.e. "create") something, like an array, in one translation unit, but use it in multiple translation units. This is fine as long as C is concerned: everything MUST be defined ONCE, but can be used multiple times. However, you need to inform the compiler that you want the array defined in another translation unit, not to define another array. In order to do this, you use the extern keyword.
In your case, your array a is just a global array, that can be accessed from anywhere in this translation unit (i.e. in this file). So, you don't really need to declare it in the main function using the extern keyword.
What you really want to ask is whether you can create a global array with a size equal to argc.
Up until C99 (K&R is pre-C99), the size of the array must be constant. So you have to create an array big enough. However, you should not hope that it fits - this is a very common way to create bugs and vulnerabilities. Instead, you should check if its usage is sensible and if the size is exceeded, generate an error. If you don't, you get undefined behaviour. It may work, or it may not. And it may be exploited for malicious purposes.
The C99 standard suports variable length arrays, so you can have something like int a[argc];. However, this works just for a local array.
The solution would be to create a global pointer and allocate dinamically memory for it in the main function using the malloc function.
What I want is to ensure that file scope variables (in my program) can not be modified from outside the file. So I declare them as 'static' to preclude external linkage. But I also want to make sure that this variable can not be modified via pointers.
I want something similar to the 'register' storage class, in that
the address of any part of an object declared with storage-class
specifier register cannot be computed, either explicitly (by use of
the unary & operator) or implicitly (by converting an array name to a
pointer).
but without the limitations of the 'register' keyword (can not be used on file scope variables, arrays declared as register can not be indexed).
That is,
<new-keyword> int array[SIZE] = {0};
int a = array[0]; /* should be valid */
int *p = array; /* should be INVALID */
p = &array[3]; /* should be INVALID */
What is the best way to go about achieving this goal?
Why do I desire such a feature?
The usage scenario is that this file will be modified by many people in the future even when I can not personally overview all modifications. I want to preclude as many potential bugs as possible. In this case I want to make sure that variables meant to be 'private' to the module will remain so without having to depend just on documentation and/or discipline
No, I don't think you can do so, at least not cleanly. But I also fail to understand your usage case fully.
If your object is static, nobody knows its name outside of your module. So nobody can use & to take its address.
If you need to expose it, and don't want other parts of the program modifying it, write a function that exposes it as a constant pointer:
static int array[SIZE];
const int * get_array(void)
{
return array;
}
Then compile with warnings. If somebody casts away the const, it's their problem.
Assuming you are concerned with security issues, here are a few things to consider:
The purpose of register keyword was to recommend the compiler to keep that variable in a register, as it will be intensively used. As the registers don't have a memory address, it is impossible to get it (although this wasn't the primary purpose of this keyword; it is merely a side-effect). As compilers got better at generating efficient code, this is not needed any more.
Even if you could make all objects in your code "addess-proof" (impossible to get their address), the program will still not be 100% safe. Those objects are still stored in memory, which is still visible. By analysing the binary files, using debuggers, analysing the memory map and so on, one could find out those memory addresses.
This is not a good practice. In order for someone to get the variable of an object in a module, that object must be global, which is bad. So you should worry about having global variables, not about their visibility. Here you can find more details about why is it bad to have variables in the global scope.
As a semi-solution to your "problem", you can declare them const static. This way they cannot be accessed from outside the module and if it happens, no one can change their value.
C89
gcc (GCC) 4.7.2
Hello,
I am maintaining someones software and I found this function that returns the address of a static structure. This should be ok as the static would indicate that it is a global so the address of the structure will be available until the program terminates.
DRIVER_API(driver_t*) driver_instance_get(void)
{
static struct tag_driver driver = {
/* Elements initialized here */
};
return &driver;
}
Used like this:
driver_t *driver = NULL;
driver = driver_instance_get();
The driver variable is used throughout the program until it terminates.
some questions:
Is it good practice to do like this?
Is there any difference to declaring it static outside the function at file level?
Why not pass it a memory pool into the function and allocate memory to the structure so that the structure is declared on the heap?
Many thanks for any suggestions,
Generally, no. It makes the function non-reentrable. It can be used with restraint in situations when the code author really knows what they are doing.
Declaring it outside would pollute the file-level namespace with the struct object's name. Since direct access to the the object is not needed anywhere else, it makes more sense to declare it inside the function. There's no other difference.
Allocate on the heap? Performance would suffer. Memory fragmentation would occur. And the caller will be burdened with the task of explicitly freeing the memory. Forcing the user to use dynamic memory when it can be avoided is generally not a good practice.
A better idea for a reentrable implementation would be to pass a pointer to the destination struct from the outside. That way the caller has the full freedom of allocating the recipient memory in any way they see fit.
Of course, what you see here can simply be a C implementation of a singleton-like idiom (and most likely it is, judging by the function's name). This means that the function is supposed to return the same pointer every time, i.e. all callers are supposed to see and share the same struct object through the returned pointer. And, possibly, thy might even expect to modify the same object (assuming no concurrency). In that case what you see here is a function-wrapped implementation of a global variable. So, changing anything here in that case would actually defeat the purpose.
As long as you realize that any code that modifies the pointer returned by the function is modifying the same variable as any other code that got the same pointer is referring to, it isn't a huge problem. That 'as long as' can be a fairly important issue, but it works. It usually isn't the best practice — for example, the C functions such as asctime() that return a pointer to a single static variable are not as easy to use as those that put their result into a user-provided variable — especially in threaded code (the function is not reentrant). However, in this context, it looks like you're achieving a Singleton Pattern; you probably only want one copy of 'the driver', so it looks reasonable to me — but we'd need a lot more information about the use cases before pontificating 'this is diabolically wrong'.
There's not really much difference between a function static and a file static variable here. The difference is in the implementation code (a file static variable can be accessed by any code in the file; the function static variable can only be accessed in the one function) and not in the consumer code.
'Memory pool' is not a standard C concept. It would probably be better, in general, to pass in the structure to be initialized by the called function, but it depends on context. As it stands, for the purpose for which it appears to be designed, it is OK.
NB: The code would be better written as:
driver_t *driver = driver_instance_get();
The optimizer will probably optimize the code to that anyway, but there's no point in assigning NULL and then reassigning immediately.
I have the following structure:
struct sys_config_s
{
char server_addr[256];
char listen_port[100];
char server_port[100];
char logfile[PATH_MAX];
char pidfile[PATH_MAX];
char libfile[PATH_MAX];
int debug_flag;
unsigned long connect_delay;
};
typedef struct sys_config_s sys_config_t;
I also have a function defined in a static library (let's call it A.lib):
sys_config_t* sys_get_config(void)
{
static sys_config_t config;
return &config;
}
I then have a program (let's call it B) and a dynamic library (let's call it C). Both B and C link with A.lib. At runtime B opens C via dlopen() and then gets an address to C's function func() via a call to dlsym().
void func(void)
{
sys_get_config()->connect_delay = 1000;
}
The above code is the body of C's func() function and it produces a segmentation fault when reached. The segfault only occurs while running outside of gdb.
Why does that happen?
EDIT: Making sys_config_t config a global variable doesn't help.
The solution is trivial. Somehow, by a header mismatch, the PATH_MAX constant was defined differently in B's and C's compilation units. I need to be more careful in the future. (facepalms)
There is no difference between the variable being a static-local, or a static-global variable. A static variable is STATIC, that means, it is not, on function-call demand, allocated on the stack within the current function frame, but rather it is allocated in one of the preexisting segments of the memory defined in the executable's binary headers.
That's what I'm 100% sure. The question, where in what segment they exactly placed, and whether they are properly shared - is an another problem. I've seen similar problems with sharing global/static variables between modules, but usually, the core of the problem was very specific to the exact setup..
Please take into consideration, that the code sample is small, and I worked on that platforms long time ago. What I've written above might got mis-worded or even be plainly wrong at some points!
I think, that the important thing is that you are getting that segfault in C when touching that line. Setting an integer field to a constant could not have failed, never, provided that target address is valid and not write-protected. That leaves two options:
- either your function sys_get_config() has crashed
- or it has returned an invalid pointer.
Since you say that the segfault is raised here, not in sys_get_config, the only thing left is the latter point: broken pointer.
Add to the sys_get_config some trivial printf that will dump the address-to-be-returned, then do the same in the calling function "func". Check whether it not-null, and also check if within sys_get_config it is the same as after being returned, just to be sure that calling conventions are proper, etc. A good idea for making a double/triple check is to also add inside the module "A" a copy of the function sys_get_config (with different name of course), and to check whether the addresses returned from sys_get_config and it's copy are the same. If they are not - something went very wrong during the linking
There is also a very very small chance that the module loading has been deferred, and you are trying to reference a memory of a module that was not fully initialized yet.. I worked on linux very long time ago, but I remember that dlopen has various loading options. But you wrote that you got the address by dlsym, so I suppose the module has loaded since you've got the symbol's final address..
Is there any difference in these two? If so, what exactly is the difference? Assume they are in a C function that may be called multiple times.
declare and assign in same statement
static uint32_t value = x; // x varies and may be passed into function.
declare in one statement and assign in next statment.
static uint32_t value;
value = x; // x varies;
Is value updated only the first time it is declared/initialized or even on subsequent calls.
My understanding of (1) is that it is only set the first time that line is executed so even if x changes the next time the line executes, value will remain the same. I am not sure about (2) but clarification on both will be very helpful
EDIT: Compiler ARM(ADS1.20).
EDIT: A follow up question on (2) from the answers given so far. Is the declaration(not the assignment) repeated on every call or just the first time?
The first should not compile; the static variable requires a constant initializer.
The second sets value each time the function is called, so there was no need to make it static in the first place.
If the first notation was correct - initialized value to 1, say - then it would be initialized once when the program starts and would thereafter only take new values when the code changed it. The second notation still sets value on each call to the function, and so renders the use of static pointless. (Well, if you try hard enough, you can devise scenarios under which the second version has a use for static. For example, if the function returns a pointer to it that other code then modifies, then it might be needed, but that is esoteric in the extreme and would be a pretty bad 'code smell'.)
1 is only executed once, but for 2 value will be reassigned every time.
Static variables are initialized only once.
These are very different declarations.
The first one is declaring a static local variable and giving it an initial value (this should not actually compile given that x is not a constant). This will only occur once before the function is every executed. This is almost certainly the initialization you want.
The second declaration is updating the value every time the function is called. If you want the variable to always start the function with the same value this is the right approach. But if this is truly what you want, then why use a static at all? Just use a local variable.
Your intuition is right. In the second example value is set to x each time the method is called. Static variables need to be initialized and declared in one statement if you only want it to run once.
If you always want value to have the value x, don't declare it as static.
When compiled, the first one will be put into the ".data" section, where data is initialized, while the second one will be put into the ".bss" section, where data is uninitialized.
Use readelf -S xx.o can check the section size of compiled object file.
example 1:
static int i;
void test(){
i = 2;
}
example 2:
static int i=1;
void test(){
i = 2;
}
Folks - In C, the first declaration is perfectly legal. It will compile, and could be used to initialize the value. You could combine the line of code from the second declaration to ensure it gets updated every subsequent function execution. This is commonly used, in particular in embedded programs where memory and resources are more scarce than computers or distributed applications.
The reason why you would use a static is to ensure the variable has a data lifecyle that continues throughout program execution while limiting its access to only the function the static is declared, or any function in the file if the static declaration is on top of the file, otherwise, the data will be lost every time the function is exited. This is good programming practice to avoid inadvertent access to data objects that must be secured and restricted. That comment only applies to the C programming language, don't mistake this to apply for C++ (where it does in some instances), or JAVA. Static in Java has a completely different meaning. From what I've read in this thread, few seem to understand how the keyword static works in C, and are confusing the keyword static form other languages to apply in C. In C, static is a very important keyword that helps manage function and data access, and you can initialize a static variable with another variable provided it is within scope, and you can update that value throughout program execution, which would probably what you need to do anyways.