error with own struct in c - c

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 = ...;

Related

Deleting resources

I'm a beginner in C. I currently have a task to create a program having multiple queues. How should i correct this? From my understanding, is supposed to clear all of the queues that where created. As currently i think i have memory leaks.
#include <stdio.h> //printf etc
#include <stdlib.h> //malloc calloc realloc free
#include <stdint.h>
/* number of message queues */
#define MSGQS_LEN 5
/* number of nodes in the message queue */
#define CAPACITY 5
typedef struct _node {
const char* message;
struct _node* next;
} node_t;
typedef struct {
char qName;
node_t *front, *rear;
} msg_queue_t;
typedef struct {
msg_queue_t **queues;
} MsgQs_t;
Your code has several problems.
if(msg_queues < 0)
exit(EXIT_FAILURE);
This test is not correct, msg_queues will be NULL if malloc failed for some reason, the test should read.
if(msg_queues == NULL)
exit(EXIT_FAILURE);
/* Relinquishes all resources currently held by a MsgQs_t.
The pointer to the MsgQs_t in question is set to NULL. */
MsgQs_t* unloadMsgQs(){
MsgQs_t *msg_queues;
msg_queues = NULL;
return(msg_queues);
}
You allocate a variable on the stack, initialize it to NULL and return NULL from this function.
What you actually want to do is pass a MsqQs_t* to unloadMsgQs and use this pointer as an argument to free, something like this
void unloadMsgQs(MsgQs_t *msg_q) {
if(msg_q) {
free(msg_q);
}
}
If you want to set the msg_q pointer to NULL so that it can't be reused anymore, you should probably do something like.
void unloadMsgQs(MsgQs_t **msg_q) {
if(msg_q && *msg_q) {
free(*msg_q);
*msg_q = NULL;
}
}
From what I see, my advice would be to read some more books / tutorials on programming with C and pointers in general, because it seems you don't quite grasp the basics yet (which is nothing to be ashamed of of course!)
You have to call free with the pointer value returned from malloc. For this you have to pass the pointer to unloadMsgQs as an argument.
If this function is supposed to set the pointer to NULL in the caller, you have to pass the address of the pointer.
Note that malloc's return value to indicate an error is NULL not a value < 0.
/* Returns a pointer to MsgQs_t structure and through which multiple message queues can be subsequently created.
Each individual message queue is to be identified by a unique identifier. */
MsgQs_t* initializeMsgQs(){
MsgQs_t* msg_queues;
msg_queues = malloc(sizeof(MsgQs_t));
if(msg_queues == NULL)
exit(EXIT_FAILURE);
return(msg_queues);
}
/* Relinquishes all resources currently held by a MsgQs_t.
The pointer to the MsgQs_t in question is set to NULL. */
void unloadMsgQs(MsgQs_t **msg_queues){
if(msg_queues != NULL)
{
free(*msg_queues);
*msg_queues = NULL;
}
}
/* sample use in main() */
int main(int argc, char **argv)
{
MsgQs_t* msg_queues;
msg_queues = initializeMsgQs();
/* ... */
unloadMsgQs(&msg_queues);
return 0;
}

Invalid read in hash table

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;
}

Strange characters from char array in structure

Here are my structures (defined in a header file):
typedef struct
{
char *name;
char *value;
} struct_param;
typedef struct
{
char *UID;
int number;
char *type;
char *name;
struct_param param[10];
} struct_cmd;
the prototype :
struct_cmd *ParseFile(char buffer[]);
The function in the c file:
struct_cmd *ParseFile(char buffer[])
{
struct_cmd *cmd;
cmd = malloc(sizeof(struct_cmd));
...
if (mxmlGetFirstChild(node_msgUID) != NULL)
cmd->UID = node_msgUID->child->value.opaque;
...
printf("Message Type :: %s | Message UID :: %s \n", cmd->type, cmd->UID);
...
return cmd;
}
The printf in ParseFile works perfectly.
Now, from the main function:
int main(int argc, char **argv)
{
...
struct_cmd *mystruct;
mystruct = malloc(sizeof(struct_cmd));
mystruct = ParseFile(buf);
printf("Message Type :: %s | Message UID :: %s \n", mystruct->type, mystruct->UID);
...
}
The same printf doesn't work. The function returns the structure, but values are weird... It's not values, but strange characters.
Any idea?
Thanks
You are making a shallow copy from the data allocated by Mini-XML to your own struct cmd.
For example, this statement copies a pointer, not the actual characters:
cmd->UID = node_msgUID->child->value.opaque;
cmd->UID still refers to the original memory block allocated by Mini-XML. There's nothing wrong with that, just remember that this memory will be de-allocated once you call mxmlDelete. Which is probably what you are doing somewhere near the end of function ParseFile. I am guessing here, since you did not post all your code.
Possible solutions:
Instead of a shallow copy, make a deep copy, e.g. with strdup: cmd->UID = strdup(node_msgUID->child->value.opaque);
Do all processing before freeing memory.
Remember, you are programming in plain C, without a garbage collector. Memory management is your responsibility.
Just to be sure... I must use malloc before setting the value to my structure in the ParseFile function, right?
So as I said in a comment, if I manually set cmd->type = "type" in the ParseFile function, it's correctly showed in the console (in the main).
But if I don't, strange characters are displayed.
I changed the declaration of my structure and added "extern", but it didn't change anything.
I'm lost...
define cmd globally instead of locally in the function:
struct_cmd *ParseFile(char buffer[])
{
struct_cmd *cmd;
cmd = malloc(sizeof(struct_cmd));
...
if (mxmlGetFirstChild(node_msgUID) != NULL)
cmd->UID = node_msgUID->child->value.opaque;
...
printf("Message Type :: %s | Message UID :: %s \n", cmd->type, cmd->UID);
...
return cmd;
}
to:
struct_cmd *cmd;
struct_cmd *ParseFile(char buffer[])
{
cmd = malloc(sizeof(struct_cmd));
...
if (mxmlGetFirstChild(node_msgUID) != NULL)
cmd->UID = node_msgUID->child->value.opaque;
...
printf("Message Type :: %s | Message UID :: %s \n", cmd->type, cmd->UID);
...
return cmd;
}

C - segmentation fault using struct member values

I'm running head-long into a segmentation fault that I'm not sure of the reason behind.
Short story... I store file names into members of a struct, then use those members to open files to load their data into linked lists. This is working fine when I only have two file, but when I go to add a third, I get a segmentation fault opening the first file.
Code will hopefully illustrate better...
int main(int argc, char* argv[])
{
/* Initalise tennisStore struct */
TennisStoreType *ts;
systemInit(ts);
/* Variables */
ts->stockFile = "stock.csv";
ts->custFile = "customer.csv";
ts->salesFile = "sales.csv";
/* Load data from files */
loadData(ts, ts->custFile, ts->stockFile);
...
}
The struct details for ts...
typedef struct tennisStore
{
CustomerNodePtr headCust;
unsigned customerCount;
StockNodePtr headStock;
unsigned stockCount;
char *custFile;
char *stockFile;
char *salesFile;
} TennisStoreType;
systemInit() seems pretty innocuous, but here's the code just in case...
void systemInit(TennisStoreType *ts)
{
/* Set ts options to be ready */
ts->headCust = NULL;
ts->headStock = NULL;
ts->customerCount = 0;
ts->stockCount = 0;
}
loadData()...
void loadData(TennisStoreType* ts, char* customerFile, char* stockFile)
{
/* Load customer data */
addCustNode(ts, customerFile);
/* Load stock data */
addStockNode(ts, stockFile);
}
Here's where the problem occurs...
void addStockNode(TennisStoreType* ts, char* stockFile)
{
/* Variables */
StockNodePtr head, new, current, previous;
unsigned stkLevel;
char *stkTok1, *stkTok2, *stkTok3, *stkTok4;
char buf[BUFSIZ];
float stkPrice;
FILE *stream;
/* Set head */
head = NULL;
/* Open stock file */
stream = fopen(stockFile, "r"); <-- segmentation fault when sales.csv line included
assert(stream);
while (fgets(buf, BUFSIZ, stream))
{
...
}
...
}
As above, when the ts->salesFile = "sales.csv" line is included in main, the segmentation fault occurs. When it isn't, all is fine (file opens, I can read from it, write to it etc). Cannot for the life of me understand why, so I'm appealing to your good nature and superior knowledge of C for potential causes of this problem.
Thanks!
ts is uninitialized, and used as is, in systemInit().
It should be malloc()ed..
change
TennisStoreType *ts;
to
TennisStoreType *ts=malloc(sizeof(TennisStoreType));
or
change
TennisStoreType *ts;
systemInit(ts);
to
TennisStoreType ts;
systemInit(&ts);
You never actually created your TennisStoreType object.
int main(int argc, char* argv[])
{
TennisStoreType *ts; // <-- allocates 4 bytes for a pointer
systemInit(ts); // <-- pass the pointer to nowhere around.
Try inserting ts = malloc(sizeof(TennisStoreType)) in between those two lines.

External Functions and Parameter Size Limitation (C)

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);

Resources