Can't figure out why my program is asserting - c

I'm working on an simple vector program as an assignment, but I cant figure out my why program asserts. My program compiles successfully, but fails at runtime. I think im at the reach of expertise on this one.
#include <iostream>
#include <cstring>
#include <assert.h>
#include <stdio.h>
#include <iomanip>
#define TESTING
using namespace std;
typedef float Elem;//floats for vector elements
struct Vector{//structure for the vector
unsigned int size;
Elem *svector;
};
int main(){
#ifdef TESTING
//prototypes
Vector *alloc_vec();
bool print_vec(Vector *printVector);
Vector *extend_vec(Vector *extend,Elem element);
Vector *scalar_plus(Vector *vecToAdd, Elem addElement);
void dealloc_vec(Vector *&deAlloc);
//testing scaffolds
Vector *testVec=new Vector;
*testVec=*alloc_vec();
assert(testVec->size==0);
assert(testVec->svector==NULL);
for(int i=0;i=10;i++){
*testVec=*extend_vec(testVec,Elem(i));
}
assert(testVec->size!=0);
assert(testVec->svector!=NULL);
assert(print_vec(testVec));
print_vec(testVec);
*testVec=*scalar_plus(testVec,5);
print_vec(testVec);
dealloc_vec(testVec);
assert(testVec==NULL);
#endif //testing
return 0;
}
Vector *alloc_vec(){//constructor to allocate an empty (zero-length) vector
Vector *newVector=new Vector; //initiatizes a new vector
if (newVector==NULL){
return NULL;
}
newVector->size=0;//sets length to 0
newVector->svector=NULL;//sets vector to null
return newVector;
}
bool print_vec(Vector *printVector){
if(printVector==NULL){//makes sure printVector exists to pass unit test 1
return false;
}
for(unsigned int i=0; i<printVector->size;i++){
cout<<printVector->svector[i]<<endl;
}
return true;
}
void dealloc_vec(Vector *deAlloc){
if (deAlloc==NULL){//if the vector contains no memory, no need to deallocate, unit test#1
return;}
delete deAlloc;//clears the memory of the vector
deAlloc=NULL;
return;
}
Vector *extend_vec(Vector *extend,Elem element){
if (extend==NULL){
return NULL;}
Elem *tempVec=new Elem[extend->size+1];//sets up a temp vector one size larger
tempVec[extend->size]=element;
memcpy(tempVec,extend->svector,(extend->size*sizeof(Elem)));//copies the memory from the original array to the rest of the temp array
extend->size+=1;
delete[] extend->svector;//clears the memory
extend->svector=tempVec;//the original vector now becomes the extended vector
delete[] tempVec;//clears the temporary memory
return extend;
}
Vector *scalar_plus(Vector *vecToAdd, Elem addElement){
if (vecToAdd==NULL){
return NULL;}
for(unsigned int i=0;i<vecToAdd->size;i++){//adds a scalar to each element
vecToAdd->svector[i]+=addElement;
}
return vecToAdd;
}
**EDIT
Some people asked me which assertion error I got:
Debug Assertion Failed!
Program:
...12\Projects\ConsoleApplication2\Debug\ConsoleApplication2.exe
File:f:\dd\vctools\crt_bld\self_x86\crt\src\dggdel.cpp
Line:52
Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
I've also made the following changes:
assert(testVec=NULL)
(deAlloc==NULL)
to
assert(testVec==NULL)
(deAlloc==NULL)
this function from:
void dealloc_vec(Vector *deAlloc)
to:
void dealloc_vec(Vector *&deAlloc)
Assertion error fixed, however doesnt produce output. Still working on the debugging.
Also, quite possible this is more C than C++. My prof states in the assignment spec that this is C++, but he switches between the two lots in our class.

assert(testVec=NULL);
will set testVec to NULL and evaluate as equal to that null pointer, which is false when treated as a boolean.
That should almost certainly be assert(testVec == NULL); instead.
For future reference, this is why so-called "Yoda conditions" (NULL == testVec rather than testVec == NULL) are sometimes preferred in C and C++ when comparing to a constant. If you accidentally use = rather than ==, Yoda conditions fail to compile, making the problem more obvious.
With that fixed, you have another problem: dealloc_vec nulls out its local copy of the Vector*, but that's just a copy of the real pointer; the change doesn't make it back to the caller. You might want to declare the function to take a Vector*& (a reference to a pointer). Before you do that, though, you have another assignment-instead-of-comparison to fix: if (dealloc=NULL) should be if (dealloc == NULL).
What's more, the delete[] tempvec; in extend_vec frees memory you're still using. You're begging for segfaults and heap corruption if you keep it. So delete it.

Related

How can I create a function object in C

I would like to create a wrapper for c functions, so that I can convert a function call of the form ret = function(arg1,arg2,arg3); into the form /*void*/ function_wrapper(/*void*/);. That is similar to function objects in C++ and boost bind.
Is this possible? how can I do it?
Update:
To explain in more details what I am looking for:
We start with this function:
int f(int i){
//do stuff
return somevalue;
}
Obvioulsy, it is called like this:
// do stuff
int x = 0;
ret = f(0);
// do more stuff.
I would like to do some magic that will wrap the function into void function(void)
struct function_object fo;
fo.function_pointer = &f;
fo.add_arg(x, int);
fo.set_ret_pointer(&ret);
fo.call();
Note: I saw that there was a vote for closing this question and marking it as unclear. Please do not do that. I have a legitimate need to get this question answered. If you need explanation, ask and I will be glad to elaborate.
I came up with a better code that might allow you to do what you want. First I'll explain how it works, show the code and explain why I still don't think it's a good idea to use it (though the code might open doors for improvements that addresses those issues).
Functionality:
Before you start using the "function objects", you have to call an initialization function (FUNCTIONOBJ_initialize();), which will initialize the mutexes on every data structure used in the library.
After initializing, every time you want to call one of those "function objects", without using the parameters, you will have to set it up first. This is done by creating a FUNCTIONOBJ_handler_t pointer and calling get_function_handler(). This will search for a free FUNCTIONOBJ_handler data structure that can be used at the moment.
If none is found (all FUNCTIONOBJ_handler data structures are busy, being used by some function call) NULL is returned.
If get_function_handler() does find a FUNCTIONOBJ_handler data structure it will try to lock the FUNCTIONOBJ_id_holder data structure, that holds the ID of the FUNCTIONOBJ_handler of the function about to be called.
If FUNCTIONOBJ_id_holder is locked already, get_function_handler() will hang until it's unlocked by the thread using it.
Once FUNCTIONOBJ_id_holder is locked, the ID of the grabbed FUNCTIONOBJ_handler is wrote on it and the FUNCTIONOBJ_handler pointer is returned by get_function_handler.
With the pointer in hand, the user can set the pointer to the arguments and the return variable with set_args_pointer and set_return_pointer, which both take a void * as arguments.
Finally, you can call the function you want. It has to:
1 - Grab the FUNCTIONOBJ_handler ID from the FUNCTIONOBJ_id_holder data structure and use it to get a pointer to the FUNCTIONOBJ_handler itself.
2 - Use the FUNCTIONOBJ_handler to access the arguments.
3 - Return by using one of the return function (on the example we have ret_int, which will return an integer and unlock the FUNCTIONOBJ_handler)
Below is a simplified mind map describing a bit of what is going on:
Finally, the code:
funcobj.h:
#include <stdio.h>
#include <pthread.h>
#define MAX_SIMULTANEOUS_CALLS 1024
typedef struct {
//Current ID about to be called
int current_id;
//Mutex
pthread_mutex_t id_holder_mutex;
} FUNCTIONOBJ_id_holder_t;
typedef struct {
//Attributes
void *arguments;
void *return_pointer;
//Mutex
pthread_mutex_t handler_mutex;
} FUNCTIONOBJ_handler_t;
FUNCTIONOBJ_handler_t FUNCTIONOBJ_handler[MAX_SIMULTANEOUS_CALLS];
FUNCTIONOBJ_id_holder_t FUNCTIONOBJ_id_holder;
void set_return_pointer(FUNCTIONOBJ_handler_t *this, void *pointer);
void set_args_pointer(FUNCTIONOBJ_handler_t *this, void *pointer);
void ret_int(FUNCTIONOBJ_handler_t *this, int return_value);
void FUNCTIONOBJ_initialize(void);
FUNCTIONOBJ_handler_t *get_function_handler(void);
funcobj.c:
#include "funcobj.h"
void set_return_pointer(FUNCTIONOBJ_handler_t *this, void *pointer){
this->return_pointer = pointer;
}
void set_args_pointer(FUNCTIONOBJ_handler_t *this, void *pointer){
this->arguments = pointer;
}
void ret_int(FUNCTIONOBJ_handler_t *this, int return_value){
if(this->return_pointer){
*((int *) (this->return_pointer)) = return_value;
}
pthread_mutex_unlock(&(this->handler_mutex));
}
void FUNCTIONOBJ_initialize(void){
for(int i = 0; i < MAX_SIMULTANEOUS_CALLS; ++i){
pthread_mutex_init(&FUNCTIONOBJ_handler[i].handler_mutex, NULL);
}
pthread_mutex_init(&FUNCTIONOBJ_id_holder.id_holder_mutex, NULL);
}
FUNCTIONOBJ_handler_t *get_function_handler(void){
int i = 0;
while((0 != pthread_mutex_trylock(&FUNCTIONOBJ_handler[i].handler_mutex)) && (i < MAX_SIMULTANEOUS_CALLS)){
++i;
}
if(i >= MAX_SIMULTANEOUS_CALLS){
return NULL;
}
//Sets the ID holder to hold this ID until the function is called
pthread_mutex_lock(&FUNCTIONOBJ_id_holder.id_holder_mutex);
FUNCTIONOBJ_id_holder.current_id = i;
return &FUNCTIONOBJ_handler[i];
}
main.c:
#include "funcobj.h"
#include <string.h>
//Function:
void print(void){
//First the function must grab the handler that contains all its attributes:
//The FUNCTIONOBJ_id_holder is mutex locked, so we can just access its value and
//then free the lock:
FUNCTIONOBJ_handler_t *this = &FUNCTIONOBJ_handler[FUNCTIONOBJ_id_holder.current_id];
//We dont need the id_holder anymore, free it!
pthread_mutex_unlock(&FUNCTIONOBJ_id_holder.id_holder_mutex);
//Do whatever the function has to do
printf("%s\n", (char *) this->arguments);
//Return the value to the pointed variable using the function that returns an int
ret_int(this, 0);
}
void *thread_entry_point(void *data){
int id = (int) data;
char string[100];
snprintf(string, 100, "Thread %u", id);
int return_val;
FUNCTIONOBJ_handler_t *this;
for(int i = 0; i < 200; ++i){
do {
this = get_function_handler();
} while(NULL == this);
set_args_pointer(this, string);
set_return_pointer(this, &return_val);
print();
}
return NULL;
}
int main(int argc, char **argv){
//Initialize global data strucutres (set up mutexes)
FUNCTIONOBJ_initialize();
//testing with 20 threads
pthread_t thread_id[20];
for(int i = 0; i < 20; ++i){
pthread_create(&thread_id[i], NULL, &thread_entry_point, (void *) i);
}
for(int i = 0; i < 20; ++i){
pthread_join(thread_id[i], NULL);
}
return 0;
}
To compile: gcc -o program main.c funcobj.c -lpthread
Reasons to avoid it:
By using this, you are limiting the number of "function objects" that can be running simultaneously. That's because we need to use global data structures to hold the information required by the functions (arguments and return pointer).
You will be seriously slowing down the program when using multiple threads if those use "function objects" frequently: Even though many functions can run at the same time, only a single function object can be set up at a time. So at least for that fraction of time it takes for the program to set up the function and actually call it, all other threads trying to run a function will be hanging waiting the the data structure to be unlocked.
You still have to write some non-intuitive code at the beginning and end of each function you want to work without arguments (grabbing the FUNCTIONOBJ_handler structure, unlocking the FUNCTIONOBJ_id_holder structure, accessing arguments through the pointer you grabbed and returning values with non-built-in functions). This increases the chances of bugs drastically if care is not taken, specially some nasty ones:
Increases the chances of deadlocks. If you forget to unlock one of the data structures in any point of your code, you might end up with a program that works fine at some moments, but randomly freeze completely at others (because all function calls without arguments will be hanging waiting for the lock to be freed). That is a risk that happens on multithreaded programs anyways, but by using this you are increasing the amount of code that requires locks unnecessarily (for style purposes).
Complicates the use of recursive functions: Every time you call the function object you'll have to go through the set up phrase (even when inside another function object). Also, if you call the recursive function enough times to fill all FUNCTIONOBJ_handler structures the program will deadlock.
Amongst other reasons I might not notice at the moment :p

Global variables in C on STM32

I'm working on a project where I need to use one variable declared in a certain file (say mylib.c) in the main function using 'extern'. All headers are included with guard words to avoid multiple inclusions.
The variable is a structure(defined in mylib.h) which members are only floats and integers.It's initialized at the beginning of the main function.
After entering the main's loop, and doing some work, some members that aren't concerned get random values.
So,I removed extern from the declaration in main, and instead placed it in the declaration in mylib.c. And it worked.
Sim808.h
#ifndef _SIM808_H
#define _SIM808_H
typedef struct{
uint8_t GPRS_Active;
float gsm_latitude;
float gsm_longitude;
}SIM808;
void sendCmd(const char cmd[]);
void sim808_init(void);
void parse_gsm_location(uint8_t* line);
#endif
Sim808.c
#include "sim808.h"
SIM808 sim808;
void parse_gsm_location(uint8_t* line)
{
uint8_t commas=0,index=0;
uint16_t err;
if((err=atoi((const char*)line+12))!=0)
{
printf("No coordinates received\n");
if(err==404 || err==601)
sim808.GPRS_Active=0;
return;
}
while (line[index]!= '\0' && index <50)
{
if(line[index]==',')
{
commas++;
switch (commas)
{
case 1:
sim808.gsm_longitude=atof((const char*)(line+index+1));
printf("Long:%f\n",sim808.gsm_longitude);
break;
case 2:
sim808.gsm_latitude=atof((const char*)(line +index+1));
printf("Longitude%f Latitude%f\n",sim808.gsm_longitude,sim808.gsm_latitude);
break;
case 3:
sscanf((const char*)(line+index+1),"%4d/%2d/%2d", (int*)&sim808.gsmDate.year,(int*)&sim808.gsmDate.month,
(int*)&sim808.gsmDate.day);
break;
case 4:
sscanf((const char*)(line+index+1),"%2d/%2d/%2d",
(int*)&sim808.gsmTime.hours,(int*)&sim808.gsmTime.minutes,(int*)&sim808.gsmTime.seconds);
break;
}
}
index++;
}
}
main.c
#include "sim808.h"
extern SIM808 sim808;
int main(void)
{
uint8_t response[150];
//init functions
while(1)
{
if(sim808.GPRS_Active==1)
{
sendCmd("AT+CIPGSMLOC=1,1\r\n");
HAL_UART_Receive(&huart4,response,2,60000);//max response time is 1 min
HAL_UART_Receive(&huart4,response,150,1000);//we dont need first 2 chars
parse_gsm_location(response);
memset((void*)response,0,150);
}
else
sim808_init();
}
}
As you can see,the member GPRS_Active can only receive 1 or 0 in my code.
Using printf, it turned to become 242 after the first iteration.
Can someone explain? Can this be a compiler bug?
Thanks.
The chance it is a compiler issue is really small. More likely is that your variable is modified by some part of your code. Try to avoid using global variables as they have the largest scope.
Do you use somewhere local variable with same name?
Have you checked map file or in debugger where it is placed?
You can use debugger feature datawatch where you break if data at certain address changes to help you track this issue.
When I use global variables, I do not declare them in the .h file to avoid issues of multiple inclusions. You can of course find some tricks to declare them in the .h, but I think it makes things so complicated. So try this:
In mylib.c:
int myGlobalVariable;
In main.c
extern int myGlobalVariable;
int main(void)
{
myGlobalVariable = 5;
}
If you still have issues, try to increase the size of your stack. If the stack is not big enough, it could be overwritten by other data.
If you use memset or memcpy in any of your code, make sure that the length parameter is correct. memset and memcpy are quite dangerous and you could easily write in some part of the memory that you don't really want.

Modified struct in some functions changes pointer and causes free() to fail

Pardon me for running multiple statements on one line, but this is what I don't understand. I have three functions named function1, function2 and function3 and each call makeblock, makeblock2, and makeblock3 respectively. See code below. I was trying to get them all to produce the same result on the screen. makeblock function works properly and the result after calling function1 is:
1 A
2 B
function2 and function3 do not work properly and produce a segmentation fault when attempting to free the memory pointer. I suspect it has to do with how the pointer is handled in makeblock2 and makeblock3 functions respectively.
So basically, I'm looking for a shortcut to making the data accessible without returning a modified address value back to the caller. Something shorter than block* dat=*datain;block** data=&dat; would be ideal provided it works yet my attempts in makeblock2 and makeblock3 have failed.
This is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct{int a;char b;} block;
void printdata(block* data){
while(data->a != 0){printf("%d %c\n",data->a,data->b);data++;}
}
void makeblock3(block** datain){
block** data=&(*datain);
(**data).a=1;(**data).b='A';(*data)++;
(**data).a=2;(**data).b='B';(*data)++;
}
void makeblock2(block** datain){
block** data=datain;
(**data).a=1;(**data).b='A';(*data)++;
(**data).a=2;(**data).b='B';(*data)++;
}
void makeblock(block** datain){
block* dat=*datain;block** data=&dat;
(**data).a=1;(**data).b='A';(*data)++;
(**data).a=2;(**data).b='B';(*data)++;
}
void function1(){block* data=calloc(1,100000);makeblock(&data);printdata(data);free(data);}
void function3(){block* data=calloc(1,100000);makeblock3(&data);printdata(data);free(data);}
void function2(){block* data=calloc(1,100000);makeblock2(&data);printdata(data);free(data);}
int main(){function3();return 0;}
Simple solution: don't pass by reference
void makeblock(block* data){
data->a=1; data->b='A'; data++;
data->a=2; data->b='B'; data++;
}
If you really want to pass by reference but don't want the referred object to change (which is contrary to the usual reason to pass by reference), then make a copy of the referred-to object:
void makeblock(block** data_p){
block* data = *data_p;
data->a=1; data->b='A'; data++;
data->a=2; data->b='B'; data++;
}

Bad memory access while calling function

Actually i developing using unit test.
But i break down my code in other form to ask for the error that i faced.
I have these declaration in my header file
typedef struct
{
void *topOfStack;
}Stack;
typedef enum {NUMBER,OPERATOR,IDENTIFIER}Token;
int operatorEvaluate(Stack *numberStack , Stack *operatorStack);
void * pop(Stack *stack);
The following is the respective source file
#include "try.h"
void *pop(Stack *numberStack)
{
Token *newToken = NUMBER;
return newToken;
}
int operatorEvaluate(Stack *numberStack , Stack *operatorStack)
{
Token *first = (Token*)pop (numberStack);
if(numberStack != operatorStack)
{
if(*first == NUMBER)
return 1;
}
return 0;
}
This is the source file that i call the functions which is main
#include "try.h"
#include <stdio.h>
int main ()
{
Stack numberStack;
Stack operatorStack;
int num;
num = operatorEvaluate(&numberStack , &operatorStack);
printf("This is the returned value: %d",num);
return 0;
}
When i tried to compile, the unit test tell me that bad memory access.
So i try to use eclipse to compile these, and windows tells that the .exe had stop working.
Hope someone can help me, i stuck for a long time...
Enable compiler warnings.
In particular, this makes zero sense:
Token *newToken = NUMBER;
That's a pointer, and you're assigning a value.
I cannot propose a fix, as I have no idea what you're doing.
That pop() function isn't touching the stack, and is returning an enum converted to a pointer. If you try to access anything through that pointer, it's going to provoke undefined behavior.
Your pop function is wrong in a few ways. You probably want it to actually pop your stack, rather than return a constant (which it isn't doing either, by the way!)...something like this:
void *pop(Stack *numberStack)
{
return numberStack->topOfStack;
}
but if you do that it'll still crash, because you never initialize your stack OR fill the topOfStack pointer.

Using Windows slim read/write lock

/*language C code*/
#include "windows.h"
typedef struct object_s
{
SRWLOCK lock;
int data;
} object_t, *object_p; /*own and pointer type*/
void thread(object_p x)
{
AcquireSRWLockExclusive(&x->lock);
//...do something that could probably change x->data value to 0
if(x->data==0)
free(x);
else
ReleaseSRWLockExclusive(&x->lock);
}
void main()
{
int i;
object_p object=(object_p)malloc(sizeof(object_t));
InitializeSRWLock(&object->lock);
for(i=0;i<3;i++)
CreateThread(0,0,thread,object,0);
}
As you can figure out in the codes above, what I have to accomplish is to let one thread conditionally free the object on which the other two may block. Codes above are obviously flawed because if object is set free along with the lock, all blocking threads give us nowhere but wrong.
A solution below
/*language C code*/
#include "windows.h"
typedef struct object_s
{
/*change: move lock to stack in main()*/
int data;
} object_t, *object_p; /*own and pointer type*/
void thread(void * x)
{
struct {
PSRWLOCK l;
object_p o;
} * _x=x;
AcquireSRWLockExclusive(_x->l);
//...do something that could probably change x->data value to 0
if(_x->o->data==0)
free(_x->o);
ReleaseSRWLockExclusive(&x->lock);
}
void main()
{
int i;
SRWLOCK lock; /*lock over here*/
object_p object=(object_p)malloc(sizeof(object_t));
InitializeSRWLock(&lock);
/*pack for thread context*/
struct
{
PSRWLOCK l;
object_p o;
} context={&lock, object};
for(i=0;i<3;i++)
CreateThread(0,0,thread,&context,0);
}
works in this case but not applicable however, in my final project because there is actually a dynamic linked list of objects. By applying this solution it means that there must be a list of locks accordingly, each lock for an object and moreover, when a certain object is set free, its lock must be set free at the same time. There is nothing new compared with the first code section.
Now I wonder if there is an alternative solution to this. Thank you very much!
The solution is to not allocate the lock together with the data. I would suggest that you move the data out of that struct and replace it with a pointer to the data. Your linked list can then free the data first, and then the node, without any problems. Here's some pseudo code:
typedef struct
{
lock_t lock;
int* data_ptr;
} something_t;
void init_something (something_t* thing, ...)
{
thing->lock = init_lock();
thing->data_ptr = malloc(...); // whatever the data is supposed to be
}
void free_something (somthing_t* thing)
{
lock(thing->lock);
free(thing->data_ptr);
thing->data_ptr = NULL;
unlock(thing->lock);
}
...
void linked_list_delete_node (...)
{
free_something(node_to_delete->thing);
free(node_to_delete);
}
...
void thread (void* x)
{
lock(x->lock);
//...do something that could probably change x->data_ptr->data... to 0
if(x->data_ptr->data == 0)
{
free_something(x->data_ptr->data);
}
unlock(x->lock);
}
AcquireSRWLockExclusive(lock);
if(_x->o->data==0)
free(_x);
ReleaseSRWLockExclusive(lock);
As a sidenote, a C program for Windows can never return void. A hosted C program must always return int. Your program will not compile on a C compiler.
Also, CreateThread() expects a function pointer to a function returning a 32-bit value and taking a void pointer as parameter. You pass a different kind of function pointer, function pointer casts aren't allowed in C, nor am I sure what sort of madness Windows will execute if it gets a different function pointer than what it expects. You invoke undefined behavior. This can cause your program to crash or behave in unexpected or random ways.
You need to change your thread function to DWORD WINAPI thread (LPVOID param);

Resources