char pointer becomes null within the pass of function calls - string

(5) 0x1c6235e1 in ProxyClass::Method_C (this=0xb3a0c8, sendFilePath=...) at ./src/ProxyClass.cpp:112
(6) 0x2c8706c1 in Class1::Method_B (this=0x1fc5a1, profile=0x2c8f2340 "fileProfile1", filePathAndFileName=0x0) at ./src/Class1.cpp:860
(7) 0x2c4ae4c0 in Method_B (profile=0x42c <Address 0x42c out of bounds>, filePathAndFileName=0x0) at ./src/Class1_interface.cpp:310
(8) 0x2c1e5c3c in Method_A (profile=0x42c <Address 0x42c out of bounds>, filename=0x2c601c1c "/tmp/temporaryfile.tmp") at ./src/file.cpp:890
I have the above core file snippet that is debugged with gnu gdb. This core file is created on an embedded system running Linux. There is no manipulation to the variables within the function calls...
My questions are below:
How come the profile looks like Address 0x42c out of bounds on 8th frame and while there is no change to profile until the 9th frame how can that become something meaningful("fileSchema")?
My embedded system crashes because the filename(char *) equals to 0x2c601c1c and the path is printed like this on the 8 th frame "/tmp/temporaryfile.tmp". However, again without manipulation to filename variable, Method_A calls Method_B but the char pointer suddenly becomes null on 7th frame (filePathAndFileName=0x0). Then, my system crashes. How can that char * pointer transforms to NULL with manipulation?
The crash occurs on the 6th frame because in Class1::Method_B the following line is executed "std::string filePath( filePathAndFileName);". A null char pointer is being tried to get initialized to a string and I think it causes the crash and the Abort signal (Program terminated with signal 6, Aborted.). How can I avoid that char * to become null within the pass of that variable between the methods? Any idea why it becomes null?
static TUint16 Method_A(char* profile, char* filename)
{
TUint16 a; //after the call of Method_B,the other part of this method being processed but anyway the code never passes to there because of th crash..
Method_B(profile,filename);
...
...
...
return a;
}
unsigned char Method_B_interface(char* profile, char* filePathAndFileName)
{
unsigned char returnValue = 0;
if ( callbackObject->Method_B( profile, filePathAndFileName ) )
{
returnValue = 1;
}
return returnValue;
}
bool Class1::Method_B(char* profile, char* filePathAndFileName)
{
bool returnValue = true;
std::string filePathString( filePathAndFileName );
std::string profileString( profile );
if(profileString == "fileProfile1")
{
if(xClass != NULL)
{
returnValue = xClass->Method_C(filePathString);
}
}
...
...
...
return returnValue;
}
bool ProxyClass::Method_C(const std::string& exportFilePathAndFileName)
{
bool returnValue;
std::string message = "dummy", parameters;
Serializer::serialize( message, exportFilePathAndFileName );
proxyRequest->synchCall( message, parameters );
getResponse(parameters);
Serializer::deserialize( parameters, returnValue );
return returnValue;
}

Related

C++ to C# char[]

C# code:
class Hello{
public void helloWorld(char[] chars){
//do something
}
}
C++ code to call C#:
MyCSDLL::Hello* hello;
//init hello, some calls are ok.
char* myCharPtr;
//init with message
HRESULT result = hello->helloWorld(safeArray, (MyCSDLL::_MyRetVal) _retValPtr);
Adapting from How to create and initialize SAFEARRAY of doubles in C++ to pass to C#
void createSafeArray(SAFEARRAY** saData, char* charPtr)
{
char* iterator = charPtr;
SAFEARRAYBOUND Bound;
Bound.lLbound = 0;
Bound.cElements = 10;
*saData = SafeArrayCreate(VT_R8, 1, &Bound);
char HUGEP *pdFreq;
HRESULT hr = SafeArrayAccessData(*saData, (void HUGEP* FAR*)&pdFreq);
if (SUCCEEDED(hr))
{
do {
*pdFreq++ = *iterator;
} while (*iterator++);
}
}
How to call hello->helloWorld()? it is expecting SAFEARRAY*. The current code gives 80131538 error. How to fix it?
C++ Project is not CLR.
Let's suppose the C# code is this:
namespace ClassLibrary1
{
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class Hello
{
public void helloWorld(char[] chars)
{
...
}
}
}
Then, you can call it with this C/C++ code, for example:
#import "C:\mycode\ClassLibrary1\bin\Debug\classlibrary1.tlb" raw_interfaces_only
using namespace ClassLibrary1;
HRESULT CallHello(wchar_t* charPtr, int count)
{
CComPtr<_Hello> p;
HRESULT hr = p.CoCreateInstance(__uuidof(Hello));
if (FAILED(hr))
return hr;
SAFEARRAY* psa = SafeArrayCreateVector(VT_UI2, 0, count);
if (!psa)
return E_OUTOFMEMORY;
LPVOID pdata;
hr = SafeArrayAccessData(psa, &pdata);
if (SUCCEEDED(hr))
{
CopyMemory(pdata, charPtr, count * 2); // count is the number of chars
SafeArrayUnaccessData(psa);
hr = p->helloWorld(psa);
}
SafeArrayDestroy(psa);
return hr;
}
.NET's char type is unicode, so the binary size is two bytes, the C equivalent is wchar_t (or unsigned short, etc...). So the safearray element type must match that, that's why I used VT_UI2 (VT_R8 that you used is Real of size 8 bytes, so it's equivalent to .NET's double type).
If you really want to use C's char, then you must do some kind of conversion to a 2-byte character.
Also, you can use the SafeArrayCreateVector function which directly allocates a 1-dimension safe array. Don't forget to call cleanup methods.

Change read_proc_t read_proc and write_proc_t write_proc of an existing file in /proc

I'm actually working lkm on linux 2.6.32, and I don't to understand one thing. I'm trying to change the original read_proc and write_proc of /proc/version with my functions. Thus I can to change the original value of read_proc and write_proc, with values of my function. I can see it, because values of read_proc and write_proc change to NULL to adress of my functions, but that have no effect... And I don't understand why. I don't arrive to find if version is protected (I tried to change the value of file's right with chmod), or why even after change the value, I can't write in /proc/version with echo XXXX > /proc/version. I'll be grateful for your help.
Code where I try to change values of read_proc and write_proc:
static void Proc_init()
{
int find = 0;
pde = create_proc_entry("test", 0444, NULL); //that permit to create new file in /proc, only to get some useful values
ptdir = pde->parent; //affect to ptdir the value of the pointer on /proc
if(strcmp(ptdir->name, "/proc")!=0)
{
Erreur=1;
}
else
{
root = ptdir;
remove_proc_entry("test", NULL);
ptr_subdir=root->subdir;
while(find==0)
{
printk("%s \n", ptr_subdir->name);
if(strcmp("version", ptr_subdir->name)==0)
find=1;
else
ptr_subdir=ptr_subdir->next;
}
//Save original write et read proc
old_read_proc=ptr_subdir->read_proc;
old_write_proc=ptr_subdir->write_proc;
// Before I have null values for prt_subdir->read_proc and ptr_subdir->write_proc
ptr_subdir->read_proc=&new_read_proc_t;
ptr_subdir->write_proc=&new_write_proc_t;
// after that, values of prt_subdir->read_proc and ptr_subdir- >write_proc are egual to values of &new_write_proc_t and &new_read_proc_t
}
}
static int new_read_proc_t (char *page, char **start, off_t off,int count, int *eof, void *data)
{
int len;
/* For example - when content of our_buf is "hello" - when user executes command "cat /proc/test_proc"
he will see content of our_buf(in our example "hello" */
len = snprintf(page, count, "%s", our_buf);
return len;
}
static int new_write_proc_t(struct file *file, const char __user *buf,unsigned long count, void *data)
{
/* If count is bigger than 255, data which user wants to write is too big to fit in our_buf. We don't want
any buffer overflows, so we read only 255 bytes */
if(count > 255)
count = 255;
/* Here we read from buf to our_buf */
copy_from_user(our_buf, buf, count);
/* we write NULL to end the string */
our_buf[count] = '\0';
return count;
}

Multhreaded programming in C

I have been given an assignment. There is a dictionary of 25 files and each file has random text involving random IP addresses. The task is to find out and output the count of unique IP addresses among all files using the pthread library in C.
I think I have solved the race condition on count variable by mutual exclusion. But, still there is a bug and the code has different count value in each execution.
Here is the code, please suggest fixes for the bug:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <pthread.h>
#include <string.h>
//declaring structure of arguments to give arguments to thread function
struct arg_struct
{
char *arg1; //argument 1 : to pass directory name to thread function
struct dirent *arg2; //argument 2: to pass file name to thread function
};
//declaring structure of pointer which will point unique ip addresses
struct uniqueip
{
char *ip;
};
struct filenames
{
char full_filename[256];
};
struct uniqueip u[200];
int count=0;// global count variable stores total unique ip addresses.
void *ReadFile(void *thread_no);//thread declaration
pthread_mutex_t mutex;
int main(int argc, char *argv[])
{
DIR *dir; //directory stream
FILE *file; //file stream
struct dirent *ent; // directory entry structure
char *line = NULL; // pointer to
size_t len = 1000; //the length of bytes getline will allocate
size_t read;
char full_filename[256]; //will hold the entire file path with
//file name to read
int x=0;
pthread_attr_t attr;
int rc;
long thread_no;
void *status;
void *ReadFile(void *thread_no);
// check the arguments
if(argc < 2)
{
printf("Not enough arguments supplied\n");
return -1;
}
if(argc > 2)
{
printf("Too many arguments supplied\n");
return -1;
}
struct arg_struct args;
args.arg1 = argv[1];
pthread_mutex_init(&mutex, NULL); // initializing mutex
/* Initialize and set thread detached attribute */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
// try to open the directory given by the argument
if ((dir = opendir (argv[1])) != NULL)
{
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL)
{
// Check if the list is a regular file
if(ent->d_type == DT_REG)
{
//Get the number of files first so that we would know number
//of threads to be created
x++;
}
}
}
pthread_t thread[x];
struct filenames filenames[x];
thread_no=0;
// try to open the directory given by the argument
if ((dir = opendir (argv[1])) != NULL)
{
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL)
{
// Check if the list is a regular file
if(ent->d_type == DT_REG)
{
// Create the absolute path of the filename
snprintf(filenames[thread_no].full_filename, sizeof filenames[thread_no].full_filename,
"./%s/%s", argv[1], ent->d_name);
//creating threads to read files
args.arg2 = ent; //assigning file name to argument 2
printf("main: creating thread %ld %s \n", thread_no,ent->d_name);
rc = pthread_create(&thread[thread_no], &attr, ReadFile, (void *) &args);
if (rc)
{
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
thread_no++;
}
}
// Close the directory structure
closedir (dir);
}
else
{
/* could not open directory */
perror ("");
return -1;
}
/* Free attribute and wait for the other threads*/
pthread_attr_destroy(&attr);
for(thread_no=0; thread_no<x; thread_no++)
{
rc = pthread_join(thread[thread_no], &status);
if (rc)
{
printf("ERROR; return code from pthread_join() is %d\n", rc);
exit(-1);
}
printf("Main: completed join with thread %ld having a status of %ld\n",thread_no,(long)status);
}
printf("Main: program completed. Exiting.\n");
printf("total no. of unique ip addresses are %d\n",count-1);
pthread_mutex_destroy(&mutex);
pthread_exit(NULL);
return 0;
}
void *ReadFile(void *thread_no)
{ // in thread function
struct filenames *my_data;
my_data = (struct filenames *)thread_no;
char full_filename[256];
FILE *file; //file stream
char *line = NULL;
char *split = NULL;
size_t len = 1000; // pointer to the length of bytes getline will allocate
size_t read;
const char s[2]=" "; //used as string split to get ip address
char *token;
int flag = 0,j;
// open the file
file = fopen(my_data -> full_filename, "r");
// file was not able to be open
if (file != NULL)
{
// Print out each line in the file
while ((read = getline(&line, &len, file)) != -1)
{
split=line;
token = strtok(split,s);
pthread_mutex_lock(&mutex);
if(count==0){
//locking mutex variable to avoid race condition
u[count].ip=malloc(sizeof(token)+1);
strcpy(u[count].ip,token);
printf("%d ------ %s\n",count,u[count].ip);
free(u[count].ip);
count++;
}
pthread_mutex_unlock(&mutex); // unlocking mutex
//comparing recently received ip address to all the stored unique ip address.
for(j=0;j<count;j++)
{
if(!(strcmp(u[j].ip,token)))
{
break;
}
else
{
if(j==count-1){
pthread_mutex_lock(&mutex); //locking mutex variable to avoid race condition
u[count].ip=malloc(sizeof(read));
strcpy(u[count].ip,token);
printf("%d ------ %s\n",count,u[count].ip);
count++;
free(u[count].ip);
pthread_mutex_unlock(&mutex); // unlocking mutex
}
}
}
}
}
fclose(file);
pthread_exit((void*) thread_no);
}
There's several issues in this code.
You only ever create one instance of arg_struct, but you re-use it and pass it to every thread. This means that by the time a thread starts, the value of the arg_struct you passed it may have changed. You need to give each thread its own arg_struct - eg. you could declare an array of them alongside the pthread_t array:
pthread_t thread[x];
struct arg_struct args[x];
A similar problem exists with the struct dirent * pointer inside arg_struct - the data pointed to by the struct dirent * returned by readdir() may be overwritten by the next call to readdir() on the same directory stream. There are a few ways to solve this, but one way is to replace the char *arg1; and struct dirent * in arg_struct with a buffer to hold the filename:
struct arg_struct
{
char full_filename[256]; //will hold the entire file path with
//file name to read
};
The main thread can then be changed to put the filename straight into the arg_struct:
snprintf(args[thread_no].full_filename, sizeof args[thread_no].full_filename, "./%s/%s", argv[1], ent->d_name);
In the ReadFile() function, this creates an array of one element and then tries to write to the (non-existent) second element, which has undefined behaviour:
char * argv[1];
argv[1]= my_data->arg1;
That code can be removed entirely, though - now that main() is constructing the full filename for the thread, the thread can just directly open it from the the arg_struct:
file = fopen(my_data->full_filename, "r");
(The thread doesn't need to worry about argv[1] at all anymore).
Your thread function is reading the shared count variable without holding the mutex - you need to lock the mutex before executing if (count == 0), and don't unlock it until after the for () loop (otherwise, you might get two threads deciding to add an IP to the same array location).
When you try to create a copy of the string you want to store, you aren't allocating enough space: sizeof read is always the fixed size of a size_t variable and isn't related to the size of the string you're copying. You want:
u[count].ip = malloc(strlen(token) + 1);
strcpy(u[count].ip, token);
You don't want to immediately free the u[count].ip, either: you need that string to stay allocated. Remove the free(u[count].ip); lines.
There's some easy optimisations you could make, once you get it working. For example, because count only increases and the u[] array is static below the value of count, you can lock the mutex, save a copy of count then unlock the mutex. Loop up to the saved value of count - if you find the string then you can just move straight onto the next line of your input file. It's only if you don't find the string that you need to re-lock the mutex, then continue from the saved count value up to the current count value (which might have increased in the meantime), adding the new string to the array (and incrementing count) if nececssary.

Initial assignment a Char Array using a Function in C

as we know it in C, a string defining is,
char string[] = "Hello World";
That is OK,
But I want to use a function and at initial same up,
I tried those, For example;
char * to_string()
{
return "Hello World";
}
Or;
char * to_String(void) // Function
{
char buff[16];
sprintf(buff, "%s", "Hello World");
return buff;
}
main() // main function
{
char Initial_String[] = to_String();
}
How to make this or any idea same another way.
I find what I dont send address of char Initial_String[] to fill into. No. is there Another method.
Thanks.
When you compile this, atleast in GCC, it will give you the following warning:
b.c:9: warning: function returns address of local variable
Why? Because buff[] is a local variable of function to_string(). Its scope is only inside the function to_string(). main() does not have any access to this variable. Try making buff[] a global variable instead.
Second problem: char Initial_String[] = to_String(); cannot be assigned value in this way. to_string() returns a char pointer, hence assign the value thus:
char *Initial_String = to_String();
The code below will work:
char buff[16];
char* to_String(void) // Function
{
//char buff[16]; /*this is a local variable*/
sprintf(buff, "%s", "Hello World");
return buff;
}
int main(void) // main function
{
char *Initial_String = to_String();
printf("%s", Initial_String);
return 0;
}
Yes You are right about local buffer mismake,
But This is not my wanting,
if I edit some differently,
char buff[16];
char* to_String(void) // Function
{
//char buff[16]; /*this is a local variable*/
sprintf(buff, "%s", "Hello World");
return buff;
}
int main(void) // main function
{
char *Initial_String_1 = to_String();
char *Initial_String_2 = to_String();
char *Initial_String_3 = to_String();
printf("%s", Initial_String_1 );
printf("%s", Initial_String_2 );
printf("%s", Initial_String_3 );
in this case, all strings will be same, because They have same buffer address,
I want to open the topic little more.
struct
{
long aaa;
short bbb;
int ccc;
char ddd;
.
.
. // the list goes on
}elements;
typedef struct
{
int lengt;
int *adress;
char name[10];
}_list;
char* to_String(long variable) // Function
{
sprintf(buff, "%ld", variable);
return buff;
}
int main (void)
{
_list My_List[] = {
{ sizeof(elements.aaa), &elements.aaa , to_string( elements.aaa) },
{ sizeof(elements.bbb), &elements.bbb , to_string( elements.bbb) },
{ sizeof(elements.ccc), &elements.ccc , to_string( elements.ddd) },
.
.
. //// the list goes on
};
I do not know, Do I make myself clear.
Here, string must be filled into name array, without assigning it the address.
I may have syntax mistake. the code is not tested with compiler. the idea is for illustrative purposes only.
I am trying to find a method for The purpose.
Thanks.

Why aren't these arguments valid?

//Block.h
#pragma once
class Block
{
public:
CRect pos;
int num;
public:
Block(void);
~Block(void);
};
//view class
public:
Block currentState[5]; // stores the current state of the blocks
void CpuzzleView::OnDraw(CDC* pDC)
{
CpuzzleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
//draw the 4 blocks and put text into them
for(int i=0;i<4;i++)
{
pDC->Rectangle(currentState[i].pos);
// i'm getting an error for this line:
pDC->TextOut(currentState[i].pos.CenterPoint(), currentState[i].num);
}
pDC->TextOut(currentState[i].pos.CenterPoint(), currentState[i].num);
The error says that no instance of overloaded function CDC::TextOutW() matches the argument list . But the prototype for the function is:
CDC::TextOutW(int x, int y, const CString &str )
all i've done is that instead of the 2 points i've directly given the point object returned by CenterPoint() ... shouldn't it work?
That's because you didn't supplied arguments list correctly. Please read compiler error message carefully, it's usually helps to solve the problem.
TextOut(currentState[i].pos.CenterPoint(), currentState[i].num);
In this call you passed CPoint object and int. This is not correct, you need to pass int, int and CString (or const char* and int length).
To fix this you shall do something like this:
CString strState;
strState.Format("%d", currentState[i].num); // Or use atoi()/wtoi() functions
TextOut(currentState[i].pos.CenterPoint().x, currentState[i].pos.CenterPoint().x, strState);

Resources