I'm using uthash.h in order to store my application's configuration. As the config comes from a file that is read at runtime, the keys and values within the hash are both dynamically allocated char *'s:
typedef struct config_entry {
char *name;
char *value;
UT_hash_handle hh;
} CONFIG_ENTRY;
As explained in the user guide, I implemented my own function to add keys to the config-hash that ensures uniqueness. Here it is:
void cfg_put( char *name, char *value, FREE_FLAGS flags ) {
CONFIG_ENTRY *entry;
//first, check if the key is already in the hash
HASH_FIND_STR( config_, name, entry );
if( entry == NULL ) {
//key doesn't exist yet => create new one
entry = (CONFIG_ENTRY *)malloc( sizeof( CONFIG_ENTRY ) );
entry->name = name;
HASH_ADD_KEYPTR( hh, config_, entry->name, strlen(entry->name), entry );
} else {
//key exists => possibly free existing pointers before setting value
if( (flags & FREE_NAME) == FREE_NAME ) { //
free( entry->name ); // these lines seem to be
} // problematic.
entry->name = name; //
if( (flags & FREE_VALUE) == FREE_VALUE ) {
free( entry->value );
}
}
//Finally, set the value
entry->value = value;
}
I also wrote up some testcases for checking my implementation, and they seem to run just fine. However, if I run the tests using valgrind to check for memleaks, I always get the following:
==2561== Invalid read of size 1
==2561== at 0x4026097: bcmp (mc_replace_strmem.c:541)
==2561== by 0x804ADF5: cfg_get (in /home/gj/..../test/config_test)
==2561== by 0x804B2C7: test_config1 (in /home/..../test/config_test)
==2561== by 0x402E446: run_single_test (in /usr/local/lib/libcunit.so.1.0.1)
[...]
==2561== Address 0x4194210 is 0 bytes inside a block of size 4 free'd
==2561== at 0x4023B6A: free (vg_replace_malloc.c:366)
==2561== by 0x804A872: cfg_put (in /home/..../test/config_test)
==2561== by 0x804B27D: test_config1 (in /home/..../test/config_test)
==2561== by 0x402E446: run_single_test (in /usr/local/lib/libcunit.so.1.0.1)
[...]
Here's the test case and the implementation of cfg_get for completeness:
void test_config1( void ) {
cfg_clear( FREE_ALL );
cfg_put( strdup("foo"), "bar", FREE_NONE );
CU_ASSERT_EQUAL( cfg_count(), 1 );
CU_ASSERT_STRING_EQUAL( cfg_get("foo"), "bar" );
cfg_dump();
cfg_put( "foo", "baz", FREE_NAME );
CU_ASSERT_EQUAL( cfg_count(), 2 );
CU_ASSERT_STRING_EQUAL( cfg_get("foo"), "baz" );
cfg_clear( FREE_NONE );
cfg_dump();
}
cfg_get:
char *cfg_get( const char *name ) {
CONFIG_ENTRY *entry = NULL;
HASH_FIND_STR( config_, name, entry );
if( entry ) {
return entry->value;
} else {
return NULL;
}
}
Somehow, it seems I'm accessing the old name-pointer in cfg_get after I've overwritten it in cfg_put. The problem only occurs for the name, not for the value. I'm too stupid to figure it out, thx for any advice.
You'll have to provide the complete program — that is, a complete minimal example that reproduces the valgrind issue. The code you've posted in your question looks fine, so the bug must be hiding somewhere else; e.g. in the code of cfg_clear() or cfg_count().
(Originally I thought that cfg_count() must be return HASH_COUNT(config_); — but that implementation wouldn't pass your test case, so you must be doing something weirder. Which means cfg_count is probably the wrong name for that function anyway.)
Stylistically, you might find your code easier to debug if you avoided the use of global variables (config_), and definitely you'd find it easier if you stored the "necessity to free this value" bits directly alongside the "value" bits, instead of requiring the user to keep track of FREE_NAME, FREE_VALUE, etc., on his own. That is, instead of
typedef struct config_entry {
char *name;
char *value;
UT_hash_handle hh;
} CONFIG_ENTRY;
void cfg_put(char *name, char *value, FREE_FLAGS flags);
void cfg_clear(FREE_FLAGS flags);
you should provide merely
typedef struct config_entry {
char *name;
char *value;
UT_hash_handle hh;
bool must_free_name;
bool must_free_value;
} CONFIG_ENTRY;
void cfg_put(char *name, char *value, FREE_FLAGS flags);
void cfg_clear(void);
at which point your test case becomes the more manageable
void test_config1()
{
cfg_clear(); // use the stored bits to figure out what needs freeing
cfg_put(strdup("foo"), "bar", FREE_NAME); // name is alloc'ed, so name must be freed later
CU_ASSERT_EQUAL( cfg_count(), 1 );
CU_ASSERT_STRING_EQUAL( cfg_get("foo"), "bar" );
cfg_put("foo", "baz", FREE_NONE); // neither name nor value is alloc'ed
CU_ASSERT_EQUAL( cfg_count(), 2 );
CU_ASSERT_STRING_EQUAL( cfg_get("foo"), "baz" );
}
There is a problem in your config_put() function: it modifies the key of an item already inserted in to the hash. You are not supposed to do this. It may be OK to change the name pointer to one that points to the same string, but it may be not, the implementation of uthash.h is a bit obscure.
I suggest you change the API so config_put() does all the string management, letting the config_ hash own all the strings, and no longer call strdup() in test_config1. This is much simpler and avoids the potentially complicated and error prone tracking of the life cycle of string values outside of the hash structure:
void cfg_put(const char *name, const char *value) {
CONFIG_ENTRY *entry;
//first, check if the key is already in the hash
HASH_FIND_STR(config_, name, entry);
if (entry == NULL) {
//key doesn't exist yet => create new one
entry = malloc(sizeof(*entry));
entry->name = strdup(name);
HASH_ADD_KEYPTR(hh, config_, entry->name, strlen(entry->name), entry );
} else {
//key exists => free existing value pointer if any
free(entry->value);
}
//Finally, set the value
entry->value = value ? strdup(value) : NULL;
}
Related
Let's say that I declare a C struct called foo, which has an int field called bar and a char * called baz.
How do I use the Cmocka expect_ and check_expected macros to check that the structure passed was correct and both fields have the expected values? If there is an example in the documentation, I missed it.
[Update] Perhaps I can use expect_check()? But I can't find an example :-(
Use expect_memory(...) and check_expected(...):
Example:
I assume you have a function under test fut which calls a subfunction subfunc. Your struct looks like this:
typedef struct foo_s {
int bar;
int baz;
} foo;
And your test driving function could look like this:
void test(void **state) {
foo myfoo = {
.bar = 42,
.baz = 13,
};
expect_memory(subfunc, param, &myfoo, sizeof(foo));
fut();
}
And the subfunctions could look like this:
void subfunc(foo *param){
check_expected(param);
}
Comparing the memory of the struct might work in most cases, however if your compiler puts some filler bytes in there, you have some bytes which you have no controll over and might have random values. This means that your test might not alway yield the same result, which can lead to very annoying debugging session.
For example if you have a struct like this:
typedef struct {
uint8_t c;
uint32_t i;
} tSomeStruct
You might think that the c and i are put right next to each other and sizeof( tSomeStruct ) returns 5. However if you try this out you would be surprised that it is more likely that sizeof( tSomeStruct ) actually returns 8. This is because of the mentioned filler bytes. You do not know what the values of these other bytes are. You can work around this by memsetting your structs to 0 before using them, however this is a little bit hacky and does not work in every case.
To compare structs in a clean way cmocka you can use expect_check( ... ) and check_expected( ... ). This gives you the possibility to write your own comparisson function.
Here is an example on how to use this ( Modified this example: Cmocka Gitlab )
typedef struct {
char c;
int i;
} tSomeStruct;
void mock_function( tSomeStruct* param )
{
check_expected(param)
}
/* return 1 = true, return 0 = false */
int my_int_equal_check(const LargestIntegralType value,
const LargestIntegralType check_value_data)
{
tSomeStruct* cast_value = ( tSomeStruct* ) value;
tSomeStruct* cast_check_value_data = ( tSomeStruct* ) check_value_data;
if ( ( cast_value->c == cast_check_value_data->c )
&& ( cast_value->i == cast_check_value_data->i ) ) {
return 1;
}
return 0;
}
void mytest(void **state)
{
tSomeStruct struct = {
.c = 'c',
.i = 'i',
}
expect_check(mock_function, param, my_int_equal_check, &struct);
}
I am not sure however if this is possible, if you do not pass your struct as a pointer to your function, as the check function only takes LargestIntegralType.
I recently found out that you can use the struct members inside the check_expected and expect_value:
typedef struct
{
int a;
float b;
} SomeStruct_t;
void mocked_function(SomeStruct_t* s)
{
check_expected(s->a);
check_expected(s->b);
}
void someTest(void **state)
{
expect_value(mocked_function, s->a, 3);
expect_value(mocked_function, s->b, 7.2);
// ...
}
defined in 'commando.h'
typedef struct {
int pid; /* Prozess ID */
char* name; /* Prozess Name (Programm) */
char* status; /* Status des Programms */
int check; /* bereits abgerufen? 1 - abgerufen, 0 - nicht abgerufen */
} Pstatus;
Pstatus erzeugeProzess (int neuID, char* neuName, char* neuStatus);
used in 'commando.c'
Pstatus erzeugeProzess (int neuID, char* neuName, char* neuStatus){
Pstatus erzeuge = reserviere(sizeof(struct Pstatus));
erzeuge->pid = neuID;
erzeuge->name = neuName;
erzeuge->status = neuStatus;
erzeuge->check = 0;
return erzeuge;
}
while compiling the compiler says: it's an invalid usage of an uncompleted type
and an invalid argumenttype for the erzeuge->pid ... erzeuge->check
don't know whats the Problem
anybody who can explain what I've done wrong?
first, the definition of the struct as you defined it is deprecated.
Especially using the keyword 'typedef'
which is effectively unavailable in C++, (amongst other reasons).
A much better definition of the struct is:
struct Pstatus
{
int pid; /* Prozess ID */
char* name; /* Prozess Name (Programm) */
char* status; /* Status des Programms */
int check; /* bereits abgerufen? 1 - abgerufen, 0 - nicht abgerufen */
};
then your code must reference the struct as 'struct Pstatus'.
then your code would be:
The prototype:
struct Pstatus* erzeugeProzess (int neuID, char* neuName, char* neuStatus);
The declaration:
struct Pstatus* erzeugeProzess (int neuID, char* neuName, char* neuStatus)
{
Pstatus* erzeuge = reserviere(sizeof(struct Pstatus));
if( NULL != erzeuge )
{
erzeuge->pid = neuID;
erzeuge->name = neuName;
erzeuge->status = neuStatus;
erzeuge->check = 0;
}
else
{
perror( "reserviere, %s", strerror(errno) );
}
return( erzeuge );
}
Regarding an earlier comment.
Although the stack parameters go away, by that time, the pointer to the reserved area
is already passed back to the caller.
By using a pointer in the function prototype and declaration, only a pointer
needs to be passed back, not the whole structure memory.
Also, be sure the caller checks for a NULL return value.
Also, be sure the caller performs something like free(...) to avoid a memory leak
A couple of things. One: you are allocating space for a pointer even though you are not declaring one. You want to use Pstatus *erzeuge instead. Second, you have already typedefed your struct; you no longer need to use struct Pstatus to refer to it. You want sizeof(Pstatus). In short, change your first line to:
Pstatus *erzeuge = malloc(sizeof(Pstatus));
and your code will work. Here is an ideone example as well: http://ideone.com/kHiyBg
Also, you are return statement should read:
return *erzeuge;
The alternative is to forgo pointers altogether (which it looks like is what you should be doing anyways):
Pstatus erzeuge;
erzeuge.pid = neuID;
erzeuge.name = ...;
I'm currently writing a little library of secure char and secure list (just .c/.h files that I will add to future projects) and something is bothering me, I know that some of you will think it is subjective but I think there is a "real" best way to do it. I've searched but there is nothing that give me a close answer. Here is a sample of my code.
The struct and functions used :
typedef struct _secure_list
{
cookie secret; // MUST be set to Cookie
secure_char * schar;
struct _secure_list * next;
} secure_list;
typedef struct _secure_char
{
int length; // number of characters in the string
char * str; // the string (no \0 byte at the end of the string)
} secure_char;
/**
* Create a secure list with schar
* Initialize Cookie on first use
**/
ret_value createSecureList( secure_char * scIn, secure_list ** slist )
I think there is two possible ways to write the createSecureList function :
// FIRST WAY
ret_value createSecureList( secure_char * scIn, secure_list ** slist )
{
(*slist) = NULL;
(*slist) = (secure_list *) malloc( sizeof(secure_list) );
// we copy the secure_char so it can be freed in the caller
createSecureChar("",&((*slist)->schar));
concat2SecureChar(&((*slist)->schar), scIn);
...
}
// SECOND WAY
ret_value createSecureList( secure_char * scIn, secure_list ** slist )
{
(*slist) = NULL;
(*slist) = (secure_list *) malloc( sizeof(secure_list) );
(*slist)->schar = scIn;
...
}
In my main() I have :
void main()
{
secure_list * slist_Test;
secure_char * schar_Test;
....
createSecureChar("test test",&schar_test);
createSecureList(schar_Test,&slist_Test);
....
}
My problem is that despite the fact the second way is easier to code and understand, the secure list which is a linked list will point to the same memory space as schar_Test, so if we free one of them, we free both. The first way basically create a copy of schar_Test so it can be freed in the calling function.
Can someone tell me which is the "right" way ?
I am fairly new to C and have been learning from K&R's book The C Programming Language.
After doing the exercises on Binary trees I wanted to make a header for binary trees for
char*, long and double.
There is a function in the following code that has been giving me grief - it should fill an array of character pointers with the values stored in the tree in lexicographical order however it has a bug somewhere. Here's the code for the String Tree Header btree.h:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/************** TYPES **************/
typedef struct ctree
{
char *name;
ctree *left;
ctree *right;
};
/************** Globals **************/
static int c_inc = 0;
/************** Function Prototypes **************/
ctree *add_to_c_tree (ctree *cnode, char *name);
void print_c_tree (ctree *cnode);
ctree *c_tree_alloc (void);
void c_tree_free (ctree *cnode);
void return_c_tree (ctree *cnode, char **array);
/************** Function Definitions **************/
/* add_to_c_tree() : Adds a new node to a *character binary tree */
ctree *add_to_c_tree (ctree *cnode, char *name){
/* If the node is null, allocate memory for it,
* copy the name and set the internal nodes to null*/
if(cnode == NULL){
cnode = c_tree_alloc();
cnode->name = strdup(name);
cnode->left = cnode->right = NULL;
}
/* If initialised then add to the left node if it is lexographically
* less that the node above it else add it to the right node */
else{
if(strcmp(name, cnode->name) < 0)
cnode->left = add_to_c_tree(cnode->left,name);
else if(strcmp(name, cnode->name) > 0)
cnode->right = add_to_c_tree(cnode->right,name);
}
return cnode;
}
/* print_c_tree() : Print out binary tree */
void print_c_tree(ctree *cnode){
if (cnode != NULL) {
print_c_tree(cnode->left);
printf("%s\n",cnode->name);
print_c_tree(cnode->right);
}
}
/* return_c_tree() : return array of strings containing all values in binary tree */
void return_c_tree (ctree *cnode, char **array){
if (cnode != NULL) {
return_c_tree (cnode->left,array+c_inc);
c_tree_free(cnode->left);
*(array+c_inc++) = strdup(cnode->name);
// printf("arr+%d:%s\n", c_inc-1,*(array+(c_inc-1)));
return_c_tree (cnode->right,array+c_inc);
c_tree_free(cnode->right);
}
}
/* c_tree_alloc() : Allocates space for a tree node */
ctree *c_tree_alloc(void){
return (ctree *) malloc(sizeof(ctree));
}
/* c_tree_free() : Free's Memory */
void c_tree_free (ctree *cnode){
free(cnode);
}
Which I have been testing with bt.c:
#include "btree.h"
int main(void){
ctree *node = NULL; char *arr[100];
node = add_to_c_tree(node, "foo");
node = add_to_c_tree(node, "yoo");
node = add_to_c_tree(node, "doo");
node = add_to_c_tree(node, "woo");
node = add_to_c_tree(node, "aoo");
node = add_to_c_tree(node, "boo");
node = add_to_c_tree(node, "coo");
print_c_tree(node);
return_c_tree(node,arr);
for (int i = 0; i < 7; ++i)
{
printf("%d:%s ..\n",i, arr[i]);
}
return 0;
}
The reason for this question is that I have been having issues with the return_c_tree() function, which is meant to mimic the behaviour of K&R's print_c_tree() function except instead of recursively calling itself until a NULL ptr and printing out the name of the nodes in lexicographical order it is meant to add their names to an array of character ptrs and free the nodes memory.
However the output I get when run as above is:
aoo
boo
coo
doo
foo
woo
yoo
0:aoo ..
1:(null) ..
2:boo ..
3:doo ..
4:foo ..
5:coo ..
6:(null) ..
Which shows that the print function works fine but the return function obviously isn't.
The confusing thing is that if the call to printf() in return_c_tree() is uncommented this is the result:
aoo
boo
coo
doo
foo
woo
yoo
arr+0:aoo
arr+1:boo
arr+2:coo
arr+3:doo
arr+4:foo
arr+5:woo
arr+6:yoo
0:aoo ..
1:(null) ..
2:boo ..
3:doo ..
4:foo ..
5:coo ..
6:(null) ..
Which implies that it actually does add the strings in the right order.
Also I have tried it without the c_inc variable -> ie just incrementing array
before passing it to the right node which the produces the same results from the printf
in return_c_tree() but different from main:
arr+-1:aoo
arr+-1:boo
arr+-1:coo
arr+-1:doo
arr+-1:foo
arr+-1:woo
arr+-1:yoo
0:foo ..
1:yoo ..
2:coo ..
3:(null) ..
4:(null) ..
5:(null) ..
6:(null) ..
I'm rather confused, so If anyone can help I would appreciate it greatly. I'm sure I'm just incrementing it in the wrong place but I can't work out where.
I thought I had finally understood pointers but apparently not.
Best
P
Your problem is how you handle your pointer to array when you recursively call. This will fix your return_c_tree function:
void return_c_tree (ctree *cnode, char **array)
{
if (cnode != NULL) {
return_c_tree (cnode->left,array); // <--- CHANGED 2ND PARAM
c_tree_free(cnode->left);
*(array+c_inc++) = strdup(cnode->name);
return_c_tree (cnode->right,array); // <--- AGAIN, CHANGED 2ND PARAM
c_tree_free(cnode->right);
}
}
You're using a global variable c_inc to keep track of the current index into the array. However, when you recursively called return_c_tree, you passed in array+c_inc, but you did not offset c_inc to account for this. Basically, you double-counted c_inc each time.
While this solves your particular problem, there are some other problems with your code.
In general, using global variables is asking for trouble. There's no need to do it here. Pass c_inc as a parameter to return_c_tree.
Also, mixing global variables with recursion is especially prone to problems. You really want recursive routines to keep their state on the stack.
As a commenter pointed out, all of your code in btree.h should really be in btree.c. The point of header files is to define an interface, not for code.
(This is more stylistic) Your return_c_tree function is really two distinct functions: copy the elements of the tree (in order) into the array, and free the memory used by the tree. These two operations are conceptually distinct: there are times that you'll want to do one and not both. There can be compelling performance (or other) reasons to mix the two, but wait until you have some hard evidence.
I am very much stuck in the following issue. Any help is very much appreciated!
Basically I have a program wich contains an array of structs and I am getting a segmentation error when I call an external function. The error only happens when I have more than 170 items on the array being passed.
Nothing on the function is processed. The program stops exactly when accessing the function.
Is there a limit for the size of the parameters that are passed to external functions?
Main.c
struct ratingObj {
int uid;
int mid;
double rating;
};
void *FunctionLib; /* Handle to shared lib file */
void (*Function)(); /* Pointer to loaded routine */
const char *dlError; /* Pointer to error string */
int main( int argc, char * argv[]){
// ... some code ...
asprintf(&query, "select mid, rating "
"from %s "
"where uid=%d "
"order by rand()", itable, uid);
if (mysql_query(conn2, query)) {
fprintf(stderr, "%s\n", mysql_error(conn2));
exit(1);
}
res2 = mysql_store_result(conn2);
int movieCount = mysql_num_rows(res2);
// withhold is a variable that defines a percentage of the entries
// to be used for calculations (generally 20%)
int listSize = round((movieCount * ((double)withhold/100)));
struct ratingObj moviesToRate[listSize];
int mvCount = 0;
int count =0;
while ((row2 = mysql_fetch_row(res2)) != NULL){
if(count<(movieCount-listSize)){
// adds to another table
}else{
moviesToRate[mvCount].uid = uid;
moviesToRate[mvCount].mid = atoi(row2[0]);
moviesToRate[mvCount].rating = 0.0;
mvCount++;
}
count++;
}
// ... more code ...
FunctionLib = dlopen("library.so", RTLD_LAZY);
dlError = dlerror();
if( dlError ) exit(1);
Function = dlsym( FunctionLib, "getResults");
dlError = dlerror();
(*Function)( moviesToRate, listSize );
// .. more code
}
library.c
struct ratingObj {
int uid;
int mid;
double rating;
};
typedef struct ratingObj ratingObj;
void getResults(struct ratingObj *moviesToRate, int listSize);
void getResults(struct ratingObj *moviesToRate, int listSize){
// ... more code
}
You are likely blowing up the stack. Move the array to outside of the function, i.e. from auto to static land.
Another option is that the // ... more code - array gets populated... part is corrupting the stack.
Edit 0:
After you posted more code - you are using C99 variable sized array on the stack - Bad IdeaTM. Think what happens when your data set grows to thousands, or millions, of records. Switch to dynamic memory allocation, see malloc(3).
You don't show us what listsize is, but I suppose it is a variable and not a constant.
What you are using are variable length arrays, VLA. These are a bit dangerous if they are too large since they usually allocated on the stack.
To work around that you can allocate such a beast dynamically
struct ratingObj (*movies)[listSize] = malloc(sizeof(*movies));
// ...
free(movies);
You'd then have in mind though that movies then is a pointer to array, so you have to reference with one * more than before.
Another, more classical C version would be
struct ratingObj * movies = malloc(sizeof(*movies)*listsize);
// ...
free(movies);