Valgrind + C: Handling uninitialized pointers without error - c

Maybe I got too involved with testing my assignment, but here's my dilemma:
This is my offending function (more or less):
struct thing{
char* data;
}
int function(struct thing* arg){
if(arg->data == NULL)
return -1;
}
This is my offending input:
struct thing *x = malloc(sizeof(struct thing));
function(x);
And valgrind outputs this when I test it:
Conditional jump or move depends on uninitialised value(s)
I'm about 99% sure that this is because valgrind has an issue with evaluating x->data when it hasn't been initialized to NULL or malloced. Is there a workaround for this?

To my opinion valgrind is right in complaining here because data is in fact not initialized and function is not able to determine if it was. The function can only check if it has the defined value you used for initialization.
So I would consider using a creation function that does the initialization as well. This way you could also allocate the memory for data right away when passing its size as parameter (or just NULL if you want to do that later).
struct thing *newThing(size_t dataSize)
{
struct thing *t = malloc(sizeof (struct thing));
if (t)
t->data = malloc(sizeof(char) * dataSize);
// or t->data = NULL if it should be done later
return t;
}

You are defining a function like this:
int function(struct thing *arg) {
if (arg->data == NULL) {
// abort here
return 1;
} else {
// use the value here
return 0;
}
}
Here, Valgrind is right about complaining, because it's impossible to achieve the intended behavior for function(). If arg->data is not explicitly initialized, then its value is indeterminate, and the if statement could execute any of the two branches depending on whichever random value it reads from arg->data.
In general, it's impossible for the function to work correctly, because:
If the check arg->data == NULL fails, the rest of the code will assume that arg->data is not NULL and therefore use the invalid value, most likely causing a crash or other kind of problem.
If the check arg->data == NULL passes, the rest of the code will wrongfully assume that the data is known to be invalid, and do any other kind of thing assuming that data was intended to be NULL, like for example call some cleanup code at the wrong time.
Other than this, if you really want to be pedantic, reading uninitialized variables is actually undefined behavior in C.
The right thing to do in your case is to either use calloc() instead of malloc() or to manually set x->data = NULL right after malloc().

The memory allocated by malloc is not initialized.
You need to set it to the know state:
struct thing *x = calloc(1,sizeof(*x));
or
struct thing *x = malloc(sizeof(*x));
memset(x, 0, sizeof(*x);
you can also of course just assign some values to the struct members,
struct thing *x = malloc(sizeof(*x));
x -> data = NULL;

Related

Initialising struct through a function whose members are dynamic arrays

I have the following struct definition (names have been generalised):
typedef struct structure{
int *array1;
int *array2;
} structure_t;
I need to initialise this struct data structure through a function which takes in the sizes of the two arrays as parameters. The function returns a pointer to that data structure and NULL on fail.
I am getting confused on how to go about this. I know that I cannot return a pointer of a locally declared struct, and I also know that I need to dynamically allocate memory for the two members array1 and array2, since the size is not known on compile time (it's inputted by this user). I have tried the following:
structure_t* init(int size1, int size2)
{
structure_t *st = malloc(sizeof (structure_t));
if(st == NULL) return NULL;
st->array1 = malloc((sizeof (int))*size1);
st->array2 = malloc((sizeof (int))*size2);
return st;
}
I have checked and everything is being initialised. But then when I come to free the memory it is not working properly, as only the pointer to array1 is being changed to NULL.
bool destroy(strcuture_t *st)
{
free(st->array1);
free(st->array2);
free(st);
if (st == NULL)
return true;
else
return false;
}
What am I doing wrong?
free does not change the value of the pointer passed to it. It cannot, as it receives only the value and not a reference to the pointer.
To record that a pointer no longer points to valid memory, you can set the pointer to NULL yourself after calling free, as with:
free(st);
st = NULL;
Further, once the memory pointed to by st is freed, the C standard does not define the behavior of accessing st->array1 or st->array2 or even of using the value of st at all. There is no reason to expect that checking st->array1 or st->array2 for a null pointer will produce any particular result. The comparison may evaluate to true, may evaluate to false, may cause your program to abort, or may cause your program to misbehave in other ways.

BOOLEAN allocate_items(struct item * items, size_t howmany) function for allocate an array of struct item

Recently, I'm learning C. I found a question on the internet. The question is:
What is the problem with this function in terms of memory allocation?
What is a good solution? You may assume that a struct item type has
been declared. The purpose of this function is to allocate an array of
struct item, which you may assume has been declared prior to this
function.
BOOLEAN allocate_items(struct item * items, size_t howmany)
{
size_t count;
items = malloc(sizeof(struct item) * howmany);
if(!items) {
perror("failed to allocate memory");
return FALSE;
}
return TRUE;
}
So, I think that the 4th line is wrong. It should be like:
items = malloc(sizeof(struct item));
And also the 6th line is wrong. It should be like:
if(items == NULL){
Is it correct?
First of all, both line 4 and 6, as you mentioned seems to be OK.
That said, the basic problem with this function is, you're allocating memory to a local scope of variable. This way
as you don't return the pointer to allocated memory, after the function returns, there would be no way to access the allocated memory.
by not freeing up the allocated memory, you will face memory leak.
If you have to allocate memory to a pointer, you need to pass the address of that pointer to the function and allocate memory. You can also return the pointer but then you need to change the function signature.
Finally, arrays are not pointers and vice-versa. They may appear or beahave similar sometimes, but they are not the same.
The 4th line is not wrong as they are trying to declare an array of the structs.
You should add a line inside the function that declares a new pointer, temp, to hold the current value of items, then after allocating the memory,
the 6th line should be
if(items == temp)
to check whether the value has changed(because that is the closest we can get to checking whether malloc worked)
this is because the ! operator is used to check if a condition is true or not(at least at a basic level in most languages) and as a pointer isn't a condition or an int that can be used as true or false, the operator won't work.
Here a fixed version, as it would probably be written in the "industry".
bool allocate_items(struct item ** pitems, size_t howmany)
{
// argument validation
assert(NULL != pitems); // some also add release version checks...
if(NULL == pitems ) return false;
// We can also spot memory leak sources here.
// If *pItems != NULL - does that mean we have to free first to prevent
// a leak? What if it is just some random value and not something we can
// free? So contract usually is: *pitems has to be NULL...
assert(NULL == *pitems);
if(NULL != *pitems) return false;
// implementation
*pitems = malloc(sizeof(struct item) * howmany);
if(NULL == *pitems) {
perror("failed to allocate memory");
}
return NULL != *pitems;
}
While the bool defined in stdbool.h sometimes causes trouble with C++ interop (same symbols on both sides, but sometimes sizeof(bool) differs), it is still the better option compared to inventing yet another bool type.
The pitems is a pointer to the location where the pointer to the new chunk of memory shall be written to. A caller of this function might have written:
int main(int argc, const char*[] argv) {
struct item *myBunchOfStuff = NULL;
if(false != allocate_items( &myBunchOfStuff, 20) ) {
// ...
free(myBunchOfStuff);
myBunchOfStuff = NULL;
}
return 0;
}
Defensive programming states: Your function cannot claim "Heh - my function only crashed because I was given a bad value!". Instead, it has to verify itself. It is responsible not to crash. The pointer could still be != NULL but otherwise bad. That is impossible for the function to catch, usually.
In C, everyone is proud of not requiring the cast of malloc()'s return value. You can be proud of that until you compile your code with a C++ compiler. Then you have to change your code and fix that. Well, I guess it is a matter of preference...
While parameter checking is often seen as a separate part of the functions implementation, after that, you should try to stick to "single point of exit". Main reason for that is maintainability. With multiple exit points, if the function gets bigger later on, it gets harder to spot if some early exit forgets to free some memory or cleanup other forms of state.

How do you pass a struct Pointer in C?

I am a little confused by how pointers are passed in functions by reference?
For instance, here's some code that I have written
(I didn't copy the entire function, just the part of it that is relevant)
metadata * removeBlock(metadata *first)
{
metadata *temp = first;
if(first == NULL || first -> prev == NULL)
{
first -> in_use = 1;
first = NULL;
return temp;
}
}
What I want is that when the function returns, the original value passed in should be set to NULL.
Here is how I call the function, (this line of code will pull a metadata structure from a region in heap, it works correctly, I have debugged and made sure that after this, struct really points to a valid metadata struct)
metadata *strct = ((metadata *)ptr - sizeof(metadata));
removeBlock(strct);
However, after this method returns, strct is still the same value it was before I had passed it in the function. I tried passing in &strct, but that just threw an invalid cast exception. What is the best way to pass in the struct as an argument?
Thankyou.
I don't think what you want is a good design - if the user of your function wants the pointer set to null (why?) it would make sense to reset the value using the return value from your function.
Anyway, you'll want a pointer-to-a-pointer, like so:
metadata* removeBlock(metadata** first) {
metadata* temp = *first;
if( temp == NULL ) return temp;
if( temp->prev == NULL ) {
temp->in_use = true;
*first = NULL;
}
return temp;
}
metadata* strct = ((metadata*)ptr - sizeof(metadata));
removeBlock(&strct);
As #SheerFish said, all we have in C is pass-by-value. However, one can simulate pass-by-reference with a pointer.
void func(struct foo **fooptr) { *fooptr = 0; }
int main(int argc, char **argv) { struct foo *fooptr; func(&fooptr); }
This is passing a pointer ptr to the variable's value (never mind if that value was a pointer), allowing the function to play with the original value with *ptr. This technique is sometimes called pass-by-address, and is the closest C has to pass-by-reference.
If you pass by 'reference in C', you're going to need to keep in mind referencing and de referencing via ->/** and *. This bit of code I wrote may help you a bit
int delete_node(struct node** head, int target)
{
if(*head == NULL)
return 0;
if((*head)->data == target)
{
temp = *head;
*head = (*head)->next;
free(temp);
return 1;
}
}
Function call:
delete_node(&head, data)
You're working with direct memory pointer manipulation. You're tossing the location of the struct in memory, de referencing it, then changing the value at that memory location.
I didn't read all of the details, but this part jumped out as incorrect:
(metadata *)ptr - sizeof(metadata)
Pointer arithmetic is done in the units of the type, whereas sizeof gives you measurements in bytes.
So I suspect what you're trying to say is:
(metadata *)(((char*)ptr) - sizeof(metadata))
This is also making some assumptions about the machine you're running on, i.e. metadata may need to be padded to ensure that the fields are properly aligned for this use. If sizeof(metadata) is not a multiple of the word size, this will fail on a lot of architectures. (But x86 will let it slide, albeit with performance costs and some implications like atomic ops not working on the fields.)
pointers are passed by value. anything in c is passed by value. so in order to change the pointer passed to the function, it should receive metadata **first.
besides, you should use
metadata *strct = ((metadata *)ptr - 1);
as pointer arithmetic is done with multiples of sizeof(*p). so this is equivalent to
metadata *strct = ((metadata *)((char*)ptr - sizeof(metadata)));

Modifying struct members through a pointer passed to a function

for instance this code:
struct test{
int ID;
bool start;
};
struct test * sTest;
void changePointer(struct test * t)
{
t->ID = 3;
t->start = false;
}
int main(void)
{
sTest->ID = 5;
sTest->start = true;
changePointer(sTest);
return 0;
}
If I was to execute this code, then what would the output be? (i.e. if I pass a pointer like this, does it change the reference or is it just a copy?)
Thanks in advance!
Your program doesn't have any output, so there would be none.
It also never initializes the sTest pointer to point at some valid memory, so the results are totally undefined. This program invokes undefined behavior, and should/might/could crash when run.
IF the pointer had been initialized to point at a valid object of type struct test, the fields of that structure would have been changed so that at the end of main(), ID would be 3. The changes done inside changePointer() are done on the same memory as the changes done in main().
An easy fix would be:
int main(void)
{
struct test aTest;
sTest = &aTest; /* Notice the ampersand! */
sTest->start = true;
changePointer(sTest);
return 0;
}
Also note that C before C99 doesn't have a true keyword.
The only question is why do you need a test pointer in a global name space? Second is that you do not have any memory allocation operations. And you have a pointer as an input parameter of your function. Therefore structure where it points to will be changed in "changePointer".
1) First thing your code will crash since you are not allocating memory for saving structure.. you might need to add
sText = malloc(sizeof(struct test));
2) After correcting the crash, you can pass structure pointer and the changes you make in changePointer function will reflect in main and vizeversa..
3) But since you are not printing anything, there wont be any output to your program..

How to return an integer from a function

Which is considered better style?
int set_int (int *source) {
*source = 5;
return 0;
}
int main(){
int x;
set_int (&x);
}
OR
int *set_int (void) {
int *temp = NULL;
temp = malloc(sizeof (int));
*temp = 5;
return temp;
}
int main (void) {
int *x = set_int ();
}
Coming for a higher level programming background I gotta say I like the second version more. Any, tips would be very helpful. Still learning C.
Neither.
// "best" style for a function which sets an integer taken by pointer
void set_int(int *p) { *p = 5; }
int i;
set_int(&i);
Or:
// then again, minimise indirection
int an_interesting_int() { return 5; /* well, in real life more work */ }
int i = an_interesting_int();
Just because higher-level programming languages do a lot of allocation under the covers, does not mean that your C code will become easier to write/read/debug if you keep adding more unnecessary allocation :-)
If you do actually need an int allocated with malloc, and to use a pointer to that int, then I'd go with the first one (but bugfixed):
void set_int(int *p) { *p = 5; }
int *x = malloc(sizeof(*x));
if (x == 0) { do something about the error }
set_int(x);
Note that the function set_int is the same either way. It doesn't care where the integer it's setting came from, whether it's on the stack or the heap, who owns it, whether it has existed for a long time or whether it's brand new. So it's flexible. If you then want to also write a function which does two things (allocates something and sets the value) then of course you can, using set_int as a building block, perhaps like this:
int *allocate_and_set_int() {
int *x = malloc(sizeof(*x));
if (x != 0) set_int(x);
return x;
}
In the context of a real app, you can probably think of a better name than allocate_and_set_int...
Some errors:
int main(){
int x*; //should be int* x; or int *x;
set_int(x);
}
Also, you are not allocating any memory in the first code example.
int *x = malloc(sizeof(int));
About the style:
I prefer the first one, because you have less chances of not freeing the memory held by the pointer.
The first one is incorrect (apart from the syntax error) - you're passing an uninitialised pointer to set_int(). The correct call would be:
int main()
{
int x;
set_int(&x);
}
If they're just ints, and it can't fail, then the usual answer would be "neither" - you would usually write that like:
int get_int(void)
{
return 5;
}
int main()
{
int x;
x = get_int();
}
If, however, it's a more complicated aggregate type, then the second version is quite common:
struct somestruct *new_somestruct(int p1, const char *p2)
{
struct somestruct *s = malloc(sizeof *s);
if (s)
{
s->x = 0;
s->j = p1;
s->abc = p2;
}
return s;
}
int main()
{
struct somestruct *foo = new_somestruct(10, "Phil Collins");
free(foo);
return 0;
}
This allows struct somestruct * to be an "opaque pointer", where the complete definition of type struct somestruct isn't known to the calling code. The standard library uses this convention - for example, FILE *.
Definitely go with the first version. Notice that this allowed you to omit a dynamic memory allocation, which is SLOW, and may be a source of bugs, if you forget to later free that memory.
Also, if you decide for some reason to use the second style, notice that you don't need to initialize the pointer to NULL. This value will either way be overwritten by whatever malloc() returns. And if you're out of memory, malloc() will return NULL by itself, without your help :-).
So int *temp = malloc(sizeof(int)); is sufficient.
Memory managing rules usually state that the allocator of a memory block should also deallocate it. This is impossible when you return allocated memory. Therefore, the second should be better.
For a more complex type like a struct, you'll usually end up with a function to initialize it and maybe a function to dispose of it. Allocation and deallocate should be done separately, by you.
C gives you the freedom to allocate memory dynamically or statically, and having a function work only with one of the two modes (which would be the case if you had a function that returned dynamically allocated memory) limits you.
typedef struct
{
int x;
float y;
} foo;
void foo_init(foo* object, int x, float y)
{
object->x = x;
object->y = y;
}
int main()
{
foo myFoo;
foo_init(&foo, 1, 3.1416);
}
In the second one you would need a pointer to a pointer for it to work, and in the first you are not using the return value, though you should.
I tend to prefer the first one, in C, but that depends on what you are actually doing, as I doubt you are doing something this simple.
Keep your code as simple as you need to get it done, the KISS principle is still valid.
It is best not to return a piece of allocated memory from a function if somebody does not know how it works they might not deallocate the memory.
The memory deallocation should be the responsibility of the code allocating the memory.
The first is preferred (assuming the simple syntax bugs are fixed) because it is how you simulate an Out Parameter. However, it's only usable where the caller can arrange for all the space to be allocated to write the value into before the call; when the caller lacks that information, you've got to return a pointer to memory (maybe malloced, maybe from a pool, etc.)
What you are asking more generally is how to return values from a function. It's a great question because it's so hard to get right. What you can learn are some rules of thumb that will stop you making horrid code. Then, read good code until you internalize the different patterns.
Here is my advice:
In general any function that returns a new value should do so via its return statement. This applies for structures, obviously, but also arrays, strings, and integers. Since integers are simple types (they fit into one machine word) you can pass them around directly, not with pointers.
Never pass pointers to integers, it's an anti-pattern. Always pass integers by value.
Learn to group functions by type so that you don't have to learn (or explain) every case separately. A good model is a simple OO one: a _new function that creates an opaque struct and returns a pointer to it; a set of functions that take the pointer to that struct and do stuff with it (set properties, do work); a set of functions that return properties of that struct; a destructor that takes a pointer to the struct and frees it. Hey presto, C becomes much nicer like this.
When you do modify arguments (only structs or arrays), stick to conventions, e.g. stdc libraries always copy from right to left; the OO model I explained would always put the structure pointer first.
Avoid modifying more than one argument in one function. Otherwise you get complex interfaces you can't remember and you eventually get wrong.
Return 0 for success, -1 for errors, when the function does something which might go wrong. In some cases you may have to return -1 for errors, 0 or greater for success.
The standard POSIX APIs are a good template but don't use any kind of class pattern.

Resources