Unable to locate the Bug - c

I was recently on The Daily WTF when I came across this old post. In it the author mentions that one of the programmers changed this code:
int main (int argc, char **argv)
{
int x;
char data_string[15];
...
x = 2;
strcpy(data_string,"data data data");
...
}
To this code:
int main (int argc, char **argv)
{
int x = 2;
char data_string[15] = "data data data";
...
}
The author goes on to mention:
[the coder] changed every single variable to be initiated on the stack
For the life of me I cannot see how this change could be harmful, and I am worried that it is a lapse in my C knowledge. What is the WTF?

I don't think the stack initialization was the problem. He was supposed to be looking for a hard-to-find memory leak, but he decided to do the initialization change instead on thousands of C files.
Although, as mentioned on wikipedia, "uninitialized variables [are] a frequent cause of bugs". You eliminate the potential for use of uninitialized variables if you take care of it at declaration. But doing that conversion to a few thousand files probably wasn't the most efficient way to find and solve the real problem.

i think the new code is better. Except I would have gone
char data_string[] = "data data data";

The only way this is worse is that it's possible that the older code never initialized (or used) the value in some code paths.
The other problem is this
char data_string[99] = "data data data";
Will initialize 99 characters rather than just the first 15. which makes this
char data_strings[99] = "";
a lot more expensive than this
char data_strings[99];
data_strings[0] = 0;
Of course, if the buffer really only needs to be big enough to hold "data data data",
then this is better
char data_string[] = "data data data";
But that makes you wonder whether it was ever necessary to copy the string into a stack variable at all.

Related

C Programming - Non static initialization of a flexible array member

I think my english is just to bad to understand the other articles about this. But anyway:
I just thought i could write a program (in C), that can store a set of cards.
Not complicated, just store values and names of cards and print them out.
I'm a beginner in C, and because i'm in the section "Strings in Structures" in my Book, i wanted to try out structures on my own. This is my Code so far:
#include <stdio.h>
struct card
{
int value;
char name[];
};
int main(void)
{
const struct card heart[13] = { {2,"two"}, {3,"three"}, {4,"four"}, {5,"five"}, {6,"six"}, {7,"seven"}, {8,"eight"}, {9,"nine"}, {10,"ten"}, {11,"jack"}, {12,"queen"}, {13,"king"}, {14,"ace"} };
int i;
for (i = 0; i < 13; ++i)
{
printf("The card heart-%s has the value of %i", heart[i].name, heart[i].value);
}
return 0;
}
I just wanted to test if it works, so i just wrote the heart-cards in the code. If i want to compile this file, my compiler (gcc/mingw) hits me with 26 errors. It says:
"(near initialization of heart[0])"
"non static initialization of a flexible array member"
I don't really understand this. In the book, everything works as expected. I tried to rebuild the code in the book and changing the names, but it doesn't work. I think it's a problem with the strings, because if i use integers only, everything works.
In already read in another post, that every string should be allocated manually, and there was a code example, but i don't know what all the lines should mean, and i want understand what my code does, so i don't copy + paste.
Could you explain me why this doesn't work?
PS: I am writing currently in windows, so please don't use bash commands to explain or something like that.
I am also german and my english is not the "yellow of the egg", try to explain without using complex 'sentence builds' (i hope you know what i mean :D) and unusual words.
Thanks for all help!
You need to create some space for the name of each card. Easiest way to do this would be to change your struct card definition to something like:
struct card
{
int value;
char name[16]; // doesn't have to be 16, but make sure it's large enough to hold each card name plus a '\0' terminator
};
The prior answers suggest allocating a fixed length for your names. This has limitations and even dangers. It is always a good idea to avoid it all together.
e.g. You want to alter the name during the game, e.g. "Ace (Trump Card)" but that might be both too long even worse overwrite memory. (Many of the known vulnarabilities in code are caused by buffer overruns)
You are also building in a limitation; What if your game needs translating into another language?
By using pointers, you don't need to resort to either variable length structures or fixed string lengths.
You also add the ability to add API access functions that set data, allowing checks before it's written, preventing buffer overruns.
Instead of using character array (aka strings) you should use pointers in your structures. If you follow the link at the bottom I take this further and use pointers to the structures themselves.
As the pointer storage size never changes your names can be of any length and even altered later, perhaps as the game progresses.
Your card could look something like
typedef struct card
{
int value;
char * name;
}
Now the initial assignment can be done like this
card_t card_ace = {14, "Ace"};
And the values are not fixed (unless that is what you want, then you make them const).
card_ace.value = 200;
card_ace.name = "Trump card";
or an array of cards like this
card_t suit_hearts[] = {{2,"two"}, {3,"three"}, {4,"four"}, {5,"five"}, {6,"six"}, {7,"seven"}, {8,"eight"}, {9,"nine"}, {10,"ten"}, {11,"jack"}, {12,"queen"}, {13,"king"}, {14,"ace"}}
Even better make the whole thing using pointers
typedef card_t * cards_t;
cards_t mysuit = &(card_t){2,"two"}, &(card_t){3,"three"}, ...
Perhaps consider makeing the suit a structure.
typedef struct
{
char * name;
card_t ** cards;
} suit_t;
typedef card_t * cards_t[];
suit_t mysuit = {
.name = "Hearts",
.cards = (cards_t){&(card_t){2,"two"}, &(card_t){3,"three"},....}
}
* For a fully working example of the latter, demonstrating using arrays of pointers to sidestep the limitations of variable length members of fixed arrays, see this gist on github

What is the cost of unnamed scope in C?

I was playing with C++ earlier and was thinking if, in some cases, Since my C compiler refuses to let me write code such as:
for (int i = 0; i < 30; ++i)
{
...
}
I try writing something like:
#include <stdio.h>
int main(int argc, char **argv)
{
{
int i;
for (i = 0; i < 30; ++i) {
printf("%d.\n", i);
}
}
return 0;
}
The result is that I do not have this i variable in my scope for more than I need it for, and frees up i to be used for other purposes in the main scope (i wouldn't do this to i, since it's iterator by convention). So I am allowed to write silly code like:
#include <stdio.h>
int main(int argc, char **argv)
{
int i = 3;
/* my loop scope. */
{
int i;
for (i = 0; i < 30; ++i) {
printf("%d.\n", i);
}
}
printf("i remains intact! %d.\n", i);
return 0;
}
Again, I would not intentionally make real code to abuse i like this, but in many cases, especially dealing with temporary variables necessary in libc function calls, such as sem_getvalue or Windows API FormatMessage, where it is easy to clutter up the scope with many temp variables and get confused with what's going on. By using unnamed scopes, In theory, I could reduce complexity of my code by isolating these temporary variables to unnamed scopes.
The idea seems silly but compelling and I am curious if there is any cost/drawback to writing code in this style. Is there inherent issues with writing code this way, or is this a decent practice?
{
int x = 3;
{
int y = 4;
int sum = x+y;
}
}
Has no more cost than:
{
int x = 3;
int y = 4;
int sum = x+y;
}
Because braces do not translate into any machine code themselves, they are just there to tell the compiler about scope.
The fact your variables have the same name also has no effect because variable names are also just for the compiler and do not change machine code.
frees up i to be used for other purposes in the main scope
This is the flaw in your reasoning. You should not use a variable with the same name for unrelated purposes inside the same function. Apart from making the code unreadable, it opens up for all kinds of subtle bugs. Copy/paste one snippet and put it elsewhere in the function, and suddenly it is working with another variable. That is very bad practice, period.
Similarly, it is most often bad practice to have variables in different scopes but with the same name.
If you have multiple loops in the same function that all uses an interator i with the same type, simply declare it at the beginning of the function and re-use it over and over.
If you need an i with different type at different places in a function, that's a clear sign saying that you should split the function in several.
Overall, whenever you find yourself in need to use an obscure language mechanism, you need to step back and consider if you couldn't just design the program in a simpler way. This is almost always the case. Excellent programmers always strive for simplicity and never for complexity.
I don't think local variable allocation works how you think it does.
The compiler maps all the local variables memory requirements together and on entry to the function allocates an offset of that amount on the stack at one time regardless of how many you have. So allocating 20 variables takes the same time as 1.

C another Memory / Seg fault error [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
[EDIT:]
I have removed a lot of code now. And I have reduced it to a more straight forward question.
Is it OK, to pass this variable...
char Record_Info[file_length + 1];
to another function, like this:
listdir(tempdesc, 0, sockid, Record_Info);
which uses this header:
int listdir(char *dirname, int lvl, int sockid, char Record_Info[])
And the listdir() can call its-self many times?
.
* Orig Question *
I was wondering if another set of eyes can look at this please. It was working, but I added some more code (probably more sprintf, near the bottom) and now a Segmentation fault occurs.
This program creates/sends the web page, correctly, but crashes when it returns from the send_recordings_list() function back to the parsing_request() function. I don't think its necessary to understand how its formatting the data from the file, but I included that bit anyway.
For the most part, I'm using static variables, and when I attempt to free() any thing, it causes another seg fault, or gcc lib fault. Also I am unsure if passing the variables between the functions() might be causing the issue?
Also worth mentioning, a different function (not shown in here) sends out a web page which is about 4MB, I can call this one many times and it does not crash. I have placed a few // ****** at some lines which might be of interest?
Oh yes, I have not done much standard error handling yet... (I'll do it later), so assume its a spherical chicken in a vacuum.
.
So it starts at parsing_request()
goes to send_recordings_list()
goes to listdir() . (this calls its self many times)
back to send_recordings_list()
. (seg fault here)
back to parsing_request()
.
I'm hoping some will go 'ahh i see what you did fool......'
Embedded Linux 2.6.27, GCC 4.2.4, 32MB Ram
void parsing_request(int sockid, char *buff)
{
char *res_line=malloc(MAXLINE), path[MAXLINE], *line;
// Cut code
if (strcmp(line, "/recordings_body.htm") == 0)
{
send_recordings_list (sockid); // ****** IT GOES HERE 1st ******
return;
}
free (res_line);
return;
}
int send_recordings_list(int sockid)
{
int hnd;
int hnd2;
char tempdesc[MAX_PATH_LENGTH];
// Copy all of the data <1 MiB (Slow reading)
int file_length = lseek (hnd2, 0, SEEK_END);
char Record_Info[file_length + 1]; // ******
lseek (hnd2, 0, SEEK_SET);
read (hnd2, Record_Info, file_length);
close (hnd2);
// Cut out code
del_file_cnt = 0;
sprintf (tempdesc, "%s/Recordings", TOPPY_DIR);
listdir(tempdesc, 0, sockid, Record_Info); // ***** Major 2nd call here
return 0;
}
int listdir(char *dirname, int lvl, int sockid, char Record_Info[])
{
int i;
DIR* d_fh;
struct dirent* entry;
char longest_name[4096];
char tempdesc[4096], morespace[128];
int row_col;
char chan_name[128], alt_name[128], desc[500], category[128], rec_time[14], start_time[14], end_time[14];
char trim_file_name[128], trim_file_name2[128], trim_alt_name[128], file_links[1535];
char logo[128];
int length, u_score, dot;
char *looky_pos1, *looky_pos2;
int is_match;
struct tm tm_rec, tm_start, tm_end;
time_t tim_rec, tim_start, tim_end;
// Cut out code
return 0;
}
Sorry, this is a hopeless mess. Learn how to use Linux tools like valgrind and gdb. Check carefully that the memory you request is eventually freed once and after its use is done. Check that you don't pass pointers to local variables out of functions. Check that your strings are long enough to accomodate the data expected (or check as part as your as of now nonexistent error handling).
One debugging strategy that is suprisingly effective is the Teddy Bear Consultant: Get a teddy bear and explain your problem to it step by step. Only if that doesn't help is a real human warranted. [It works because sorting out your understanding to explain it forces you to really think it through.]
After looking quickly at your code, you have two options:
Learn how to handle errors, how to manage resources and how to avoid global variables
Use a programming language which does it for you
Both will take a long time but using the second approach, you will be much more productive.
I suggest to try to implement the above with Python just to get a feeling.
Answering your most recent post, asking if you can pass the character value into the function... I don't understand what you're trying to do. In the function prototype you have the final parameter as a char variable_name[], are you trying to pass a array in? If so, why not use a pointer?
so the prototype would like like:
int listdir(char *dirname, int lvl, int sockid, char* Record_Info);
Passing by reference always tends to give you a little bit more control, whether you want it or not. Are you trying to pass in a specific element of an array?

Pointer to a char array[10] for ptr++ arithmetic

My post tries to kill 2 birds with 1 stone. Sorry in advance for the ignorance.
I'm trying to create an array of strings that I can index[0] or use ptr++ to advance the array. I'm not sure if I should create an array of char pointers, or a pointer to a char array. The variables will be stored in a struct. Forgive the ignorance, I'm just having a hard time with the order of precedence of when and where to use (). I understand a basic struct, it was when I started using a pointer to a string when I started to loose syntax structure. If I can understand the syntax for this, I could apply it further to dimensional structures of arrays.
Assuming I had the assignment of the variables correct, I think I rather use ptr++ in regards to something like printf("%s", ptr++). If I understand correctly, ptr++ would move the pointer to the next string, or some for of ptr++ could. This correct? Seems like that would be faster for many, many things.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Umbrella {
char *name[10];
} Umbrella;
int main ()
{
struct Umbrella * ptr;
// Not understanding this way...
ptr->name[0] = "Some name";
// or this way. Well name++ as long as it wasn't the first string.
ptr->name++ = "Some name";
return 0;
}
Boot note: I have read "C Primer Plus" by Prata. He does well in explaining things, it is just when you start bending things to your will when you start to fall short on applying the syntax. In example, it never covered using pointers to structures to access multidimensional arrays, and it didn't cover pointer arithmetic in a manner of syntax where you would actual use it. Can anyone recommend another book that might at least braze by such approaches?
P.S. This is my second post, and I forgot to say I really like this sites text input design. Had to say it :-).
Well, there's char *name[10] which is really just something like :
char *name0;
char *name1;
char *name2;
// .. etc
Accessing it as ptr->name[0] will just pick the ptr->name0 as a char*.
ptr->name++ = "asdf"; is a pretty bad idea here. What it basically does is :
*(ptr->name) = "asdf";
ptr->name += 1;
Of course, you can't increase name by one here (it's an array, not a pointer) so the compiler won't allow it.
The ++ operator can be useful when iterating past objects. Example :
ptr->name[9] = nullptr; // Make sure the last element is a NULL pointer.
// Take the first element
char **it = ptr->name;
char *current;
// Loop until we reach the NULL
while ((current = *(it++)) != nullptr) {
printf("%s\n", current);
}
The above is a (pretty ugly) way of iterating through an array.
Inserting things in a pre-allocated array:
char **it = ptr->name; // Start at the first element
*(it++) = "Hi!";
*(it++) = "This is the second message.";
*(it++) = "Hello world!";
*(it++) = nullptr; // End the array
Of course, all of this iteration stuff is from a dark past: nowadays we have C++ which takes care of most of these things for us, via std::vector, etc.

Sacrificing expression of intent for memory management

I'm pretty new at C programming, and this type of thing keeps popping up. As a simple example, suppose I have a struct http_header with some char pointers:
struct http_header {
char* name;
char* value;
};
I want to fill an http_header where value is the string representation of an int. I "feel" like, semantically, I should be able to write a function that takes in an empty header pointer, a name string, and an int and fills out the header appropriately.
void fill_header(struct http_header *h, char* name, int value)
{
h->name = name;
char *value_str = malloc(100);
sprintf(value_str, "%d", value);
h->value = value_str;
}
int main(int argc, const char * argv[])
{
struct http_header h;
char *name = "Header Name";
int val = 42;
fill_header(&h, name, val);
...
free(h.value);
}
Here, the calling code reads exactly as my intent, but in this case I'm creating the value string dynamically, which means I'd have to free it later. That doesn't smell right to me; it seems like the caller then knows too much about the implementation of fill_header. And in actual implementations it may not be so easy to know what to free: consider filling an array of http_headers where only one of them needed to have its value malloced.
To get around this, I'd have to create the string beforehand:
void fill_header2(struct http_header *h, char* name, char *value_str)
{
h->name = name;
h->value = value_str;
}
int main(int argc, const char * argv[])
{
struct http_header h;
char *name = "Header Name";
int value = 42;
char value_str[100];
sprintf(value_str, "%d", value);
fill_header2(&h, name, value_str);
}
As this pattern continues down the chain of structures with pointers to other structures, I end up doing so much work in top level functions the lower level ones seem hardly worth it. Furthermore, I've essentially sacrificed the "fill a header with an int" idea which I set out to write in the first place. I'm I missing something here? Is there some pattern or design choice that will make my life easier and keep my function calls expressing my intent?
P.S. Thanks to all at Stackoverfow for being the best professor I've ever had.
Well, I would go with the first approach (with a twist), and also provide a destroy function:
struct http_header *make_header(char *name, int value)
{
struct http_header *h = malloc(sizeof *h);
/* ... */
return h;
}
void destroy_header(struct http_header *h)
{
free(h->name);
free(h);
}
This way the caller doesn't have to know anything about http_header.
You might also get away with a version that leaves the main allocation (the struct itself) to the caller and does it's own internal allocation. Then you would have to provide a clear_header which only frees that fill allocated. But this clear_header leaves you with a partially-valid object.
I think your problem is simply that you are programming asymmetrically. You should once and for all decide who is responsible for the string inside your structure. Then you should have two functions, not only one, that should be called something like header_init and header_destroy.
For the init function I'd be a bit more careful. Check for a 0 argument of your pointer, and initialize your DS completely, something like *h = (http_header){ .name = name }. You never know if you or somebody will end up in adding another field to your structure. So by that at least all other fields are initialized with 0.
If you are new at C programming, you might perhaps want to use the Boehm's conservative garbage collector. Boehm's GC works very well in practice, and by using it systematically in your own code you could use GC_malloc instead of malloc and never bother about calling free or GC_free.
Hunting memory leaks in C (or even C++) code is often a headache. There are tools (like valgrind) which can help you, but you could decide to not bother by using Boehm's GC.
Garbage collection (and memory management) is a global property of a program, so if you use Boehm's GC you should decide that early.
The general solution to your problem is that of object ownership, as others have suggested. The simplest solution to your particular problem is, however, to use a char array for value, i.e., char value[12]. 2^32 has 10 decimal digits, +1 for the sign, +1 for the null-terminator.
You should ensure that 1) int is not larger than 32-bits at compile-time, 2) ensure that the value is within some acceptable range (HTTP codes have only 3 digits) before calling sprintf, 3) use snprintf.
So by using a static array you get rid of the ownership problem, AND you use less memory.

Resources