error: v.contents[30] is used uninitialized in this function - c

Here is my struct;
typedef struct _values {
int contents[MAX_CONTENTS];
... more ints;
} values;
In another function, I initialize this particular array with;
int contents[MAX_CONTENTS] = {0};
for (i = 0; i < MAX_CONTENTS; i++) {
v.contents[i] = contents[i];
}
And in my main I have this;
values v;
newValues (v);
I am getting the error whenever I try to modify an element in main like this;
v.contents[30] = 3;
This is the only error I am getting. What am I doing wrong?

v (and contents inside of it) may be getting passed by value. Change the prototype of your function to this:
void newValues(values *v);
Change how you're calling it to this:
newValues(&v);
And rather than:
v.contents[i] = /* ... */;
Use:
v->contents[i] = /* ... */;

You probably intend to copy like this:
for (i = 0; i < MAX_CONTENTS; i++) {
v.contents[i] = contents[i];
}

Related

Ignore output parameters in C

I have a function which returns some value and some parameters:
uint8 myFunction(uint8* param1);
uint8 myFunction(uint8* param1)
{
*param1 = 3;
return 1;
}
Later in my code I would like to use the function once with returning a value like:
uint8 a;
uint8 b;
a = myFunction(b);
...
...
and once with just ignoring the parameter, like:
a = myFunction(void);
How to do this in C?
I'd recommend adding a NULL check before dereferencing param1 - that would be wise anyway. Then you can just pass NULL where you want to ignore it.
uint8 myFunction(uint8* param1)
{
if (param1 != NULL)
{
*param1 = 3;
}
return 1;
}
calling code can then just pass NULL:
a = myFunction(NULL);
Of course, it would be good to clearly document this behavior.

How do I use the value of a variable in a function else where?

I have a certain program that lets you register members and save their name and birthdate into arrays. The particular function that does this registration uses the following code;
char regmember (struct member a[])
{
int i = 0;
char wow;
do
{
//registration
printf("\n Do you want to add someone else (y/n):");
scanf(" %c",&wow);
i++
}while(wow != 'n');
int nrofmembers = i;
return nrofmembers;
}
-> I save the user input by using
scanf("%s",a[i].name) and scanf("%d",&a[i].ID);
which is why I am using i++. As you realize, the int variable i, will hold the number of members who have been registered. I want to utilize this info in order to use it in loops in other functions, so I went on to save the value of i in another int variable...
int nrofmembers = i;
My problem is, I can't use that variable (nrofmembers) else where, even though I tried returning it, any advice?
you need both to get i in parameter and to return the new value, you can do
int regmember (struct member a[], int i)
{
... use and modify i
return i;
}
or using it as an input-output variable
void regmember (struct member a[], int * i)
{
... use and modify *i
}
In the first case the caller do for instance :
int i = 0;
for (...) {
...
i = regmember(..., i);
...
}
and in the second case :
int i = 0;
for (...) {
...
regmember(..., &i);
...
}
Suppose you keep the members in a global array, then you can manage how many members are in your array also as a global variable, for example
struct member gMembers[MAX_MEMBERS];
int gnMembers;
Your function can now operate on this array directly:
int regmember (void)
{
if (gnMembers < MAX_MEMBERS)
{
// add member
if (scanf("%s",gMembers[gnMembers].name)==1
&& scanf("%d",&gMembers[gnMembers].ID)==1) {
gnMembers++;
return 1; // success
}
}
return 0; // array full or scanf error
}

Initialize int array in struct in C

I have written a type:
typedef struct
{
int Tape[TAPE_SIZE];
int *Head;
int Tape_Count;
int Loop_Start_Count;
} Tarpit;
I try to initialize this type with the following function:
void Tarpit_Initialize(Tarpit Tarpit)
{
Tarpit.Tape_Count = 0;
Tarpit.Loop_Start_Count = 0;
int Index;
for(Index = 0; Index < TAPE_SIZE; Index++)
{
Tarpit.Tape[Index] = INITIAL_SIZE;
}
}
However, it does not seem to work. If I run this:
Tarpit Foo;
Tarpit_Initialize(Foo);
printf("Tarpit Initialization Test: \n");
int index;
for(index = 0; index < TAPE_SIZE ; index++)
{
if(Foo.Tape[index] == INITIAL_SIZE)
{
printf("%d: %d \n", index, Foo.Tape[index]);
}
else
{
printf("%d: %d !ERROR \n", index, Foo.Tape[index]);
}
}
I get several non-zero values (I have set #define TAPE_SIZE 10000 and #define INITIAL_SIZE 0)
Moreover, if I run the test without running Tarpit_Initialize(Foo), I get exactly the same results. The initializer does not seem to work. Why/how could I implement it in an other way? I would like to set every element of Foo.Tape to zero.
Problem solved!
You are passing Tarpit by value:
void Tape_Initialize(Tarpit Tarpit)
That means it is only a copy of Tarpit. You have to pass a pointer to it to be able to modify it.
void Tape_Initialize(Tarpit* Tarpit)
and pass it as pointer (note the name of the function called!):
Tape_Initialize(&Foo);
and the use the -> operator to modify it. For instance:
Tarpit->Tape_Count = 0;
Moreover, as "Elias Van Ootegem" pointed out, you should not use sizeof(Tarpit.Tape) to get the size of the array but TAPE_LENGTH that you defined. Because sizeof() will give you a size in bytes not in elements.
Have you checked the function u are calling ??
Its "Tarpit_Initialize(Foo);"
But the Function u are using it to initialize "void Tape_Initialize(Tarpit Tarpit)".
I think even what u have implemented should work fine .

RubyInline: Error: too few arguments to function

I have the following C code:
VALUE find_index(VALUE arr, VALUE num_elements, VALUE element){
....
}
....
VALUE array_distance(VALUE arr1, VALUE arr2){
long arr1_len = RARRAY_LEN(arr1);
VALUE *c_arr2 = RARRAY_PTR(arr2);
long i;
for(i = 0; i < arr2_len; i++){
long arr1_index = find_index(arr1, arr1_len, c_arr2[i]);
....
}
}
When compiling this, I get the following error:
In function ‘VALUE array_distance(VALUE, VALUE, VALUE)’:
error: too few arguments to function ‘VALUE find_index(VALUE, VALUE, VALUE, VALUE)’
Can someone help with what is wrong here?
If you want to use your C functions in other C code inside, you need to use builder.c_raw instead of builder.c, because RubyInline actually tries to make your life easier by changing your code so you can write simple functions quickly. This is however misleading and keeps you from calling your C functions from inside other C functions, because the method signature is altered. This should get you started:
class Test
inline :C do |builder|
builder.c_raw <<-'EOC', :arity => 3
static VALUE
find_index(int argc, VALUE *argv, VALUE self) {
VALUE arr = argv[0];
VALUE num_elements = argv[1];
VALUE element = argv[2];
// actual code...
}
EOC
builder.c_raw <<-'EOC', :arity => 2
static VALUE
array_distance(int argc, VALUE *argv, VALUE self) {
long arr1_len = RARRAY_LEN(argv[0]);
VALUE *c_arr2 = RARRAY_PTR(argv[1]);
long i;
for(i = 0; i < arr2_len; i++){
VALUE[] find_index_argv = {arr1, arr1_len, c_arr2[i]};
long arr1_index = find_index(argc, find_indev_argv, self);
// more code...
}
// must have a return value!
return Qnil;
}
EOC
end
end

How to call pointer to function defined in typedef struct

what is wrong with the following code?
parseCounter1() and parseCounter1() below are two functions.
I put their pointers in const OptionValueStruct so that
they can be called accordingly when each element of option_values[]
are gone through:
typedef struct OptionValueStruct{
char counter_name[OPTION_LINE_SIZE];
int* counter_func;
} OptionValueStruct_t;
const OptionValueStruct option_values[] = {
{"Counter1", (*parseCounter1)(char*, char**)},
{"Counter2", (*parseCounter2)(char*, char**)},
};
const OptionValueStruct *option = NULL;
for(int i = 0; i< sizeof(option_values)/sizeof(OptionValueStruct_t); i++){
option = option_values + i ;
result = option->counter_func(opt_name, opt_val);
}
You have declared your counter_func member to be a pointer to an int, not a function pointer , while you have something resembling a function pointer declaration in your option values. Here's what you want (assuming your return type is int )
typedef struct OptionValueStruct{
char counter_name[OPTION_LINE_SIZE];
int (*counter_func)(char*, char**);
} OptionValueStruct_t;
const OptionValueStruct_t option_values[] = {
{"Counter1", parseCounter1},
{"Counter2", parseCounter2},
};
for(int i = 0; i< sizeof(option_values)/sizeof(OptionValueStruct_t); i++){
result = option_values[i]->counter_func(opt_name, opt_val);
// don't know what you relly want to do with result further on..
}
If you are compiling as C code (as your tag suggests), then you should change the type of option_values[] and option to OptionValueStruct_t. In C++, however, this is OK.
Alternatively, you can eliminate the trailing _t from the custom type name.

Resources