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;
}
Related
The purpose of this code is to read the following txts(d.txt,e.txt,f.txt) and do the actions that are required in order to put the alphabet with the correct order into the output.txt. The code suppose to work since in output.txt i get the correct results but there is a problem with the testing i did using the printf (it's at the end of newfile function). In order to run i give as input d.txt and output.txt.
It should print
top->prev points to file :d
top->prev points to file :e
but instead it prints the following and i can't find the reason
top->prev points to file :d
top->prev points to file :f
d.txt:
abc
#include e.txt
mno
e.txt:
def
#include f.txt
jkl
f.txt:
ghi
code:
%{
#include <stdio.h>
#include <stdlib.h>
struct yyfilebuffer{
YY_BUFFER_STATE bs;
struct yyfilebuffer *prev;
FILE *f;
char *filename;
}*top;
int i;
char temporal[7];
void newfile(char *filename);
void popfile();
void create();
%}
%s INC
%option noyywrap
%%
"#include " {BEGIN INC;}
<INC>.*$ {for(i=1;i<strlen(yytext)-2;i++)
{
temporal[i-1]=yytext[i];
}
newfile(temporal);
BEGIN INITIAL;
}
<<EOF>> {popfile();
BEGIN INITIAL;
}
%%
void main(int argc,int **argv)
{
if ( argc < 3 )
{
printf("\nUsage yybuferstate <filenamein> <filenameout>");
exit(1);
}
else
{
create();
newfile(argv[1]);
yyout = fopen(argv[2], "w");
yylex();
}
system("pause");
}
void create()
{
top = NULL;
}
void newfile(char *filename)
{
struct yyfilebuffer *newptr;
if(top == NULL)
{
newptr = malloc(1*sizeof(struct yyfilebuffer));
newptr->prev = NULL;
newptr->filename = filename;
newptr->f = fopen(filename,"r");
newptr->bs = yy_create_buffer(newptr->f, YY_BUF_SIZE);
top = newptr;
yy_switch_to_buffer(top->bs);
}
else
{
newptr = malloc(1*sizeof(struct yyfilebuffer));
newptr->prev = top;
newptr->filename = filename;
newptr->f = fopen(filename,"r");
newptr->bs = yy_create_buffer(newptr->f, YY_BUF_SIZE);
top = newptr;
yy_switch_to_buffer(top->bs); //edw
}
if(top->prev != NULL)
{
printf("top->prev points to file : %s\n",top->prev->filename);
}
}
void popfile()
{
struct yyfilebuffer *temp;
temp = NULL;
if(top->prev == NULL)
{
printf("\n Error : Trying to pop from empty stack");
exit(1);
}
else
{
temp = top;
top = temp->prev;
yy_switch_to_buffer(top->bs);
system("pause");
}
}
You need to think about how you manage memory, remembering that C does not really have a string type in the way you might be used to from other languages.
You define a global variable:
char temporal[7];
(which has an odd name, since globals are anything but temporary), and then fill in its value in your lexer:
for(i=1;i<strlen(yytext)-2;i++) {
temporal[i-1]=yytext[i];
}
There are at least three problems with the above code:
temporal only has room for a six-character filename, but nowhere do you check to make sure that yyleng is not greater than 6. If it is, you will overwrite random memory. (The flex-generated scanner sets yyleng to the length of the token whose starting address is yytext. So you might as well use that value instead of computing strlen(yytext), which involves a scan over the text.)
You never null-terminate temporal. That's OK the first time, because it has static lifetime and will therefore be filled with zeros at program initialization. But the second and subsequent times you are counting on the new filename to not be shorter than the previous one; otherwise, you'll end up with part of the previous name at the end of the new name.
You could have made much better use of the standard C library. Although for reasons I will note below, this does not solve the problem you observe, it would have been better to use the following instead of the loop, after checking that yyleng is not too big:
memcpy(temporal, yytext + 1, yyleng - 2); /* Copy the filename */
temporal[yyleng - 2] = '\0'; /* NUL-terminate the copy */
Once you make the copy in temporal, you give that to newfile:
newfile(temporal);
And in newfile, what we see is:
newptr->filename = filename;
That does not copy filename. The call to newfile passed the address of temporal as an argument, so within newfile, the value of the parameter filename is the address of temporal. You then store that address in newptr->filename, so newptr->filename is also the address of temporal.
But, as noted above, temporal is not temporary. It is a global variable whose lifetime is the entire lifetime of the program. So the next time your lexical scanner encounters an include directive, it will put it into temporal, overwriting the previous contents. So what then happens to the filename member in the yyfilebuffer structure? Answer: nothing. It still points to the same place, temporal, but the contents of that place have changed. So when you later print out the contents of the string pointed to by that filename field, you'll get a different string from the one which happened to be in temporal when you first created that yyfilebuffer structure.
On the whole, you'll find it easier to manage memory if newfile and popfile "own" the memory in the filebuffer stack. That means that newfile should make a copy of its argument into freshly-allocated storage, and popfile should free that storage, since it is no longer needed. If newfile makes a copy, then it is not necessary for the lexical-scanner action which calls newfile to make a copy; it is only necessary for it to make sure that the string is correctly NUL-terminated when it calls newfile.
In short, the code might look like this:
/* Changed parameter to const, since we are not modifying its contents */
void newfile(const char *filename) {
/* Eliminated this check as obviously unnecessary: if(top == NULL) */
struct yyfilebuffer *newptr = malloc(sizeof(struct yyfilebuffer));
newptr->prev = top;
// Here we copy filename. Since I suspect that you are on Windows,
// I'll write it out in full. Normally, I'd use strdup.
newptr->filename = malloc(strlen(filename) + 1);
strcpy(newptr->filename, filename);
newptr->f = fopen(filename,"r");
newptr->bs = yy_create_buffer(newptr->f, YY_BUF_SIZE);
top = newptr;
yy_switch_to_buffer(top->bs); //edw
if(top->prev != NULL) {
printf("top->prev points to file : %s\n",top->prev->filename);
}
}
void popfile() {
if(top->prev == NULL) {
fprintf(stderr, "Error : Trying to pop from empty stack\n");
exit(1);
}
struct yyfilebuffer temp = top;
top = temp->prev;
/* Reclaim memory */
free(temp->filename);
free(temp);
yy_switch_to_buffer(top->bs);
system("pause");
}
Now that newfile takes ownership of the string passed to it, we no longer need to make a copy. Since the action clearly indicates that you expect the argument to the #include to be something like a C #include directive (surrounded either by "..." or <...>), it is better to make that explicit:
<INC>\".+\"$|"<".+">"$ {
/* NUL-terminate the filename by overwriting the trailing "*/
yytext[yyleng - 1] = '\0';
newfile(yytext + 1);
BEGIN INITIAL;
}
I have the header file as:
test.h
//Mandatory fields size macro
#define size_uid 65
#define size_txn 33
#define size_adhaarNo 13
#define size_ver 4
#define size_input 65
#define size_photo 1024*1024*10
#define size_pseudonym 50
#define size_name 50
//Mandatory fields declaration
char uid[size_uid];
char txn[size_txn];
char adhaarNo[size_adhaarNo];
char ver [size_ver];
char *photo;
char pseudonym[size_pseudonym];
char name[size_name];
char input[size_input];
void incorrect_val_test(FILE *, FILE *, FILE *, FILE *, FILE *, FILE *,FILE *,FILE *,FILE *,FILE*);
test.c
#include "test.h"
//Mandatory fields declaration
char uid[] = "865A80A01C70A9E0D5FC5F4D354A9155BF58CD483B1397C92614E5BC92317ACC";
char txn[] = "23da7b99-c561-4102-9df8-d37fbfe1";
char adhaarNo[] = "250241800087";
char ver [] = "1.0";
char *photo = (char *)malloc(sizeof(char)*size_photo);
char pseudonym[] = "2b6c55566d14459991513fb00bce34ed";
char name[] = "Amarjeet Sharma";
char input[] = "936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af";
void incorrect_val_test(FILE *ver, FILE *ts, FILE *txn, FILE *vtxn, FILE *uid, FILE *input, FILE *adhaarNo, FILE *photo, FILE *name, FILE *pseudonym)
{
//Some initialization and files are opened here....
photo = (char *)malloc(sizeof(char)*size_photo);
FILE *photos = fopen("./input/data.txt","r");
if(photos == NULL)
{
printf("Can't open data file.\n");
return;
}
i=0;
while((read_char = fgetc(photos))!= EOF)
{
if(read_char == '\n')
continue;
photo[i]= read_char;
i++;
}
// Some more processing done here
}
main.c
int main()
{
// Some files are opened here to read data.
incorrect_val_test(fp_ver, fp_ts, fp_txn, fp_vtxn, fp_uid, fp_input, fp_adhaarNo, fp_photo, fp_name, fp_pseudonym);
return 0;
}
When I am compiling it gives the following error message
error message
warning: assignment from incompatible pointer type
[-Wincompatible-pointer-types] photo = (char
*)malloc(sizeof(char)*size_photo); error: incompatible types when assigning to type ‘FILE {aka struct _IO_FILE}’ from type ‘char’
photo[i]= read_char;
Can anybody point me where I am going wrong?
You can have a function call like
char *photo = (char *)malloc(sizeof(char)*size_photo);
inside a function. This is not allowed in global scope. Remove the global one, leave the one present inside the incorrect_val_test() function.
Moreover, please do not cast the return value of malloc() and family in C.
Solution:
define char *photo = NULL; in global scope.
As you've done, allocate memory to photo inside your incorrect_val_test(), like
char *photo = malloc(size_photo); //cast not required
// sizeof(char) is guranteed to be 1
Then , you've got FILE *photo in your incorrect_val_test() function in the function parameter list
void incorrect_val_test(..., FILE *photo, ...)
which shadows the global char * photo.
IMHO, what you want is to write
void incorrect_val_test(..., FILE *photos, ...)
^
|
and, inside the function body,
photos = fopen("./input/data.txt","r");
but, then, why to use variables names with a single character difference? Use something more verbose and easy to distinguish.
Note: After you're done using photo, don't forget to free() the allocated memory to avoid memory-leak.
You have the function
void incorrect_val_test(..., FILE *photo, ...)
Notice that you have an argument that shadows the global variable. That's the cause of your errors in the question.
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 am having a lot of trouble with this piece of code (I am not good at pointers :P). So here is the code.
printf("\n Enter the file name along with its extensions that you want to delete:-");
scanf("%s",fileName);
deletefile_1_arg=fileName;
printf("test\n");
result_5 = deletefile_1(&deletefile_1_arg, clnt);
if (result_5 == (int *) NULL) {
clnt_perror (clnt, "call failed");
}
else
{
printf("\n File is deleted sucessfully");
goto Menu2;
}
break;
Function that is getting called is as following.
int *
deletefile_1_svc(char **argp, struct svc_req *rqstp)
{
static int result;
printf("test2\n");
printf("%s",**argp);
if(remove(**argp));
{
printf("\nFile Has Been Deleted");
result=1;
}
return &result;
}
I am getting test2 on console but. It does not print value of argp / removes that perticular file. I am not sure what I am doing wrong. Please help me.
The argp is a pointer to a pointer char, and you are trying to use it as a pointer to char, try change your code to:
printf("%s", *argp);
You would also need to change your remove call to:
remove(*argp);
I always found drawing pictures helped understand pointers. Use boxes for memory addresses and a label for the box is the variable name. If the variable is a pointer, then the contents of the box is the address of another box (draw line to the other box).
You are using pointers when you don't need to. Your "deletefile1_svc" function doesn't manipulate the value of "argp" at all so it doesn't need a pointer-to-pointer. Plus your "result" doesn't need to be returned as a pointer since it is simply a numeric value. You also don't initialize result (it might be zero) or re-initialize it (it is static so it will remember the last value assigned to it).
int
deletefile_1_svc(const char *argp, struct svc_req *rqstp)
{
int result = 0; /* Initial value => failure */
if (remove (argp) == 0)
{
result = 1; /* 1 => success */
}
return result;
}
To call the function use:
result_5 = deletefile1_svc(filename, clnt);
if (result_5 == 0)
// Failed
else
// Success
That will make the code simpler and less prone to bugs.
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);