Valgrind use of unitialised value - c

I am creating a symbol table for a compiler I am writing and when I try adding to my symbol table I keep getting valgrind errors. When I call my function, I am calling my add function
stAdd (&sSymbolTable, "test", RSRVWRD, 4, 9);
and in my stAdd function it is currently
void stAdd (StPtr psSymbolTable, char *identifier, SymbolTableType type,
int addressField, int arrayDimensions)
{
int hashValue;
hashValue = hash (identifier, psSymbolTable->numBuckets);
if (psSymbolTable->spSymbolTable[hashValue] == NULL)
{
psSymbolTable->spSymbolTable[hashValue] = (StEntryPtr) malloc (sizeof(StEntry));
strcpy (psSymbolTable->spSymbolTable[hashValue]->identifier, identifier);
psSymbolTable->spSymbolTable[hashValue]->entryLevel = psSymbolTable->currentLevel;
psSymbolTable->spSymbolTable[hashValue]->type = type;
psSymbolTable->spSymbolTable[hashValue]->addressField = addressField;
psSymbolTable->spSymbolTable[hashValue]->arrayDimensions = arrayDimensions;
psSymbolTable->spSymbolTable[hashValue]->psNext = NULL;
}
}
But every time I set a value within my StEntry struckt, I get an error
Use of unitialised value of size 8
every time I set something within the if statement. Does any see where I am going wrong?
My StEntry is
typedef struct StEntry
{
char identifier[32];
SymbolTableLevel entryLevel;
SymbolTableType type;
int addressField;
int arrayDimensions;
StEntryPtr psNext;
} StEntry;

This would be a lot easier if I could see the definition of struct StEntry or even the precise valgrind error. But I'll take a wild guess anyway, because I'm feeling overconfident.
Here, you malloc a new StEntry which you will proceed to fill in:
psSymbolTable->spSymbolTable[hashValue] = (StEntryPtr) malloc (sizeof(StEntry));
This is C, by the way. You don't need to cast the result of the malloc, and it is generally a good idea not to do so. Personally, I'd prefer:
StEntry* new_entry = malloc(sizeof *new_entry);
// Fill in the fields in new_entry
psSymbolTable->spSymbolTable[hashvale] = new_entry;
And actually, I'd ditch the hungarian prefixes, too, but that's an entirely other discussion, which is primarily opinion-based. But I digress.
The next thing you do is:
strcpy (psSymbolTable->spSymbolTable[hashValue]->identifier, identifier);
Now, psSymbolTable->spSymbolTable[hashValue]->identifier might well be a char *, which will point to the character string of the identifier corresponding to this symbol table entry. So it's a pointer. But what is its value? Answer: it doesn't have one. It's sitting in a block of malloc'd and uninitialized memory.
So when strcpy tries to use it as the address of a character string... well, watching out for the flying lizards. (If that's the problem, you could fix it in a flash by using strdup instead of strcpy.)
Now, I could well be wrong. Maybe the identifier member is not char*, but rather char[8]. Then there is no problem with what it points to, but there's also nothing stopping the strcpy from writing beyond its end. So either way, there's something ungainly about that line, which needs to be fixed.

Related

Strange behaviour in C program, variable corruption after allocating memory

I have typdef of string in my C program, it looks like that:
#define WRD_LEN 100
typedef char cstring[WRD_LEN];
then at some point I declare dynamic array of this type:
int pcount = 1;
cstring *options = malloc(sizeof(cstring*)*pcount);
I add new strings to this array with use of realloc:
options = realloc(options, sizeof(cstring*)*pcount);
strcpy(options[pcount-1], //some string//);
pcount++;
and then show all entries to user, user choses one of them and that one is passed to another function:
highestof(mode, l, options[btn]);
mode is an integer, l is struct but those are irrelevant now. btn is number (int) of entry chosed by user.
Up to this point everything works just fine, problem shows up inside highestof function:
void highestof(const int mode, List l, const cstring cat) {
List *p = malloc(sizeof(List*));
here is definition of List:
struct W {
//some data
struct W *next;
};
struct List {
struct W *first;
};
So if highestof function is called with options[1], cat variable will get corrupted (it will became a set of few random symbols, like "#^?" or "^K^?") right after malloc is called i.e. before creating dynamic array of List I can use cat as much as I want, but after calling malloc it gets corrupted. Most strange thing about this is that it happens only if variable passed down to this function was in options array under index of 1 (options[btn] where btn = 1) For any other value of btn it works no problem.
I found a workaround for this, I can create a string (char s[100]) before calling malloc, copy cat value into it and use that variable instead, but it's really not resolving initial problem and it really bothers me.
sizeof(cstring*)*pcount is too small. The size calculation is amiss.
Avoid allocation errors. Use this idiom for code that is easier to write correctly, review and maintain.
Notice no type is used.
pointer = malloc(sizeof *pointer * n);
Then code becomes:
// options = malloc(sizeof(cstring*)*pcount);
options = malloc(sizeof *options * pcount);`
cstring* is just a pointer, usually four or eight bytes. sizeof (cstring*) is therefore a small number, usually four or eight.
You are not allocating enough memory for the data, just enough memory to hold pointers to the data.

Passing array of pointers to (char) to a function and assigning a string to each

What i´m trying to do is assigning strings to pointers in a vector from a separate function for that use. unfortunately i keep getting either a lot of warnings or errors or bus trap:10.
here´s the code so far here i commented where i´m having issues:
#include <stdio.h>
#include <stdlib.h>
void read_top(FILE **read,short int *L, short int *D, short int *N){
fscanf(*read,"%hd %hd %hd",L,D,N); // L being the size of the strings, D being how many strings there are and N doesn´t matter for this question
fgetc(*read); // remove \n
}
void save_words(FILE **read,char **dic,short int L,short int D){ // i´m having problems here assigning strings to the pointers
int e;
for (e = 0;e < D;e++){
*dic[e] = malloc(125);
fgets(*dic[e],L+1,*read);
fgetc(*read);
}
}
void open(FILE **read,FILE **write) {
*read = fopen("teste4.in","r");
*write = fopen("Allien_language","w");
}
void alloc(char **dic,D,L){ //i´m having problems here allocating memory for each pointer to point to
int e;
for (e = 0;e < D; e++){
*dic[e] = malloc(L);
}
}
main(){
FILE *read,*write;
open(&read,&write);
short int L,D,N;
read_top(&read,&L,&D,&N);
char *dic[D]; // here´s the array of pointers
alloc(dic,D,L); // here´s the funtion i can´t get to work
save_words(&read,dic,L,D); // here´s the function that i can´t get to work
//printf("\n%s\n",dic[0]);
}
I´ve tried multiple things, but i think the main problem is not knowing exactly how things work. this includes passing the array to the function and assigning the strings to it and allocating the memory for each pointer. I´ve also been searching in this site for my questions, where i found solutions to similar problems but didn´t understand exactly their solutions. If someone could explain me exactly how things should work i would appreciate that.
thanks in advance
When you do e.g. *dic[e] = malloc(...) you're doing it wrong. What the expression *dic[e] does is get element e of the array dic, which is a pointer to char, then you dereference the pointer giving you the value of what dic[e] is pointing to. Unfortunately dic[e] doesn't point anywhere yet, which would lead to undefined behavior and a probable crash if the compiler didn't give you an error.
And you get an error because you try to assign the pointer returned by malloc to something that's not a pointer.
So the solution? Remove the dereference, and just do e.g. dic[e] = malloc(...).
You have the same problem when you try to read the string from the file in save_words. And there you have another problem, you allocate memory for the string again, making you loose the original allocation from the alloc function, and leading to a memory leak.
The problem is that you are treating elements of the array of pointers incorrectly: rather than assigning
*dic[e] = malloc(L);
you should be assigning
dic[e] = malloc(L);
without the dereference operator.
The reason for this is that you are passing an array of uninitialized pointers, so you may not dereference them. However, you can certainly assign them, which is what dic[e] = malloc(L) does.
You have the same problem in save_words. The fix is even simpler there - you need to drop the *dic[e] = malloc(125); line, because it re-assigns a pointer that has been assigned already.
Finally, you need to remove dereference operator from this line as well:
fgets(dic[e],L+1,*read); // No asterisk in front of "dic[e]"

Copying struct to array in C

I am having a problem with creating a function that will add (copy) structure from parameter to resized array.
Here is my simplified code:
typedef struct User
{
char FirstName[32];
char LastName[32];
}
User;
User * Users
unsigned short UsersNum = 0;
void AddUser(User * NewUser)
{
Users = (User *) realloc(Users, (UsersNum + 1) * sizeof(User));
memcpy(Users[UsersNum], NewUser, sizeof(User));
UsersNum++;
}
With this I'm getting:
error: incompatible type for argument 1 of `memcpy'
I've also tried
memcpy(Users + UsersNum, NewUser, sizeof(User));
But got SEGFAULT.
How can i copy NewUser to the end of Users?
First, please don't cast the return value of malloc() in C.
Second, why do you feel you must use memcpy() here? The memcpy() function is great, but it's a rather blunt tool meant to "blindly" copy large areas of memory that have no further structure that the program is aware of. In your case, you know that the bytes you're copying make up an instance of the User type, i.e. it's simply a value of type User.
Values are typically moved around by assignment, so use that instead:
void AddUser(const User *NewUser)
{
User *UsersGrown = realloc(Users, (UsersNum + 1) * sizeof *Users);
if(UsersGrown != NULL)
{
Users = UsersGrown;
Users[UsersNum] = *NewUser;
++UsersNum;
}
}
You can see that I also made the argument const, and added some basic error-checking since realloc() can fail.
It would be a good idea to separate the allocated size of the Users array from the length of the array, so that you can grow them at different speeds and cut down on the number of calls to realloc(). In other words, allocate room for e.g. 8 elements at first, and when that is hit, double the size and realloc(), and so on. This gives much better performance if you expect many insertions.
You should ask yourself what type is User[UsersNum] ... that is User, and memcpy operates on pointers. To get address of it there is & operand. So it should be
memcpy(&Users[UsersNum], NewUser, sizeof(User));
Also please note the you are using very very inefficient way to implement the functionality. Copying/moving stuff around so much should be avoided.

Malloc and free error

In the following function, I am parsing string form a linked list and giving values to struct array. Is there any way that let me not use mallocs inside while loop.I can not handle glibc errors, so looking for other way.I tried to use char arrays instead of char* for the struct fields. But I am getting seg error. Actually the function is working, but I ahve to call the function 15000 times later, so I want to make sure it won't cause any memory trouble that time.
struct CoordNode
{
int resNum;
double coordX;
double coordY;
double coordZ;
char atomName[4];
};
void parseCrdList()
{
int resNum=1;
int tAtomNum,i;
char *tcoordX, *tcoordY, *tcoordZ, *tatomName, tresNum[5];
ccur_node=headCoord_node->next;
struct CoordNode *t;
t=malloc(numofRes*sizeof(struct CoordNode));
i=0;
while (ccur_node!=NULL)
{
tresNum=malloc(5*sizeof(char));
memcpy(tresNum,ccur_node->crdRow+26,4);
resNum=atoi(tresNum);
t[i].resNum=resNum;
tcoordX=malloc(8*sizeof(char));
memcpy(tcoordX,ccur_node->crdRow+35,7);
tcoordY=malloc(8*sizeof(char));
memcpy(tcoordY,ccur_node->crdRow+43,7);
tcoordZ=malloc(8*sizeof(char));
memcpy(tcoordZ,ccur_node->crdRow+51,7);
t[i].coordX=strtod(tcoordX,NULL);
t[i].coordY=strtod(tcoordY,NULL);
t[i].coordZ=strtod(tcoordZ,NULL);
tatomName=malloc(4*sizeof(char));
memcpy(tatomName,ccur_node->crdRow+17,3);
strcpy(t[i].atomName,tatomName);
old_ccur_node=ccur_node;
ccur_node=ccur_node->next;
//free(old_ccur_node);
i++;
}
numofRes=i;
addCoordData(t);
//free(t);
t=NULL;
}
A couple of thoughts and guesses.
First, as I mentioned before, sizeof(char) is always 1 byte in C, it's actually standard byte definition in C. So remove those as completely unnecessary and hard to read.
Back to the main problem.
You never use array of chars bigger than 8, so just make it statically 8 bytes long. If you have to call you function 15k times, that will save you tons of time(malloc takes time to allocate memory for you).
Given information from the question I guess your segfault was the cause of not initialising memory you allocated with malloc or reserved for auto char [8] with its declaration
1. You allocate (or 2nd version - declare 8-byte array) 8 bytes. It works fine. But you get 8 bytes full of trash here.
2. You copy 7 bytes from your list. And that's fine, too. But you forget to NULL terminate, so if you try to print it out back, you get segfault.EDIT If it works then probably you got lucky, because it shouldn't.
Solution
Replace char * witch char [8], remove all mallocs and frees corresponding to those char *, null terminate all your char[8] after strcpy, strncpy, or memcpy (whatever your choice is, depending on how confident you are that your data in list is correct) data to them.
Check your code with valgrind before further use, too.
It's surprising you saying this function worked for you. From what I see from your code I had a lot of memory leaks to begin with because non of those 8-byte mallocs was ever fried.
The second thing is that it looks like you're allocating array of CoordNode before knowing the actual number of data records to parse. I added proper numofRes calculation before allocation.
Since you don't modify input data you don't actually need all those mallocs and memcpy's, you can use crdRow in strtod() immediatly, assuming it has char * type.
The last thing: it's generally a bad practice to do allocation in one place and freeing data in another. So it's better you free your headCoord_node structure in a place where it was allocated, after parsing it. The decision of freeing t depends on how addCoordData(t) treats its parameter.
void parseCrdList()
{
struct CoordNode *t;
int i;
// count number of records to parse
numofRes = 0;
ccur_node = headCoord_node->next;
while (ccur_node != NULL)
{
numofRes++;
ccur_node=ccur_node->next;
}
t=malloc(numofRes*sizeof(struct CoordNode));
i=0;
ccur_node = headCoord_node->next;
while (ccur_node!=NULL)
{
t[i].resNum=atoi(ccur_node->crdRow+26);
t[i].coordX=strtod(ccur_node->crdRow+35,NULL);
t[i].coordY=strtod(ccur_node->crdRow+43,NULL);
t[i].coordZ=strtod(ccur_node->crdRow+51,NULL);
strncpy(t[i].atomName,ccur_node->crdRow+17,4);
ccur_node=ccur_node->next;
i++;
}
numofRes=i;
addCoordData(t);
//free(t); // <<< it depends on how addCoordData treats t
}

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