I am unable to find out the memcheck error when i using valgrind on the given code - memory-leaks

I am unable to detect the memory error(memcheck error) . when i run the code i see some unexpected output came. so please describe what is happening in thes code.
#include <stdio.h>
#include <stdlib.h>
char *getString()
{
char message[100]="Hello World";
char *ret = message;
return ret;
}
void test4()
{
printf("String: %s",getString());
}
int main()
{
test4();
return 0;
}

Your variable message is local to the function getString and is on the stack. After getString returns, message no longer exists, meaning that the pointer returned by getString, which was set to point to message is no longer valid.

Related

setbuf function in the following seems ok

This is from man page. Please explain why it is invalid! Thanks!
You must make sure that the space that buf points to still exists by the time stream is closed, which also
happens at program termination. For example, the following is invalid:
#include <stdio.h>
int
main(void)
{
char buf[BUFSIZ];
setbuf(stdin, buf);
printf("Hello, world!\n");
return 0;
}

C++ console application async accepting user input

I recently stumbled upon this
link and I just tried it, but it's not working as I expect.
With this code:
#include <atomic>
#include <thread>
#include <iostream>
void ReadCin(std::atomic<bool>& run)
{
std::string buffer;
while (run.load())
{
std::cin >> buffer;
if (buffer == "q")
{
run.store(false);
}
}
}
int main()
{
std::atomic<bool> run(true);
std::thread cinThread(ReadCin, std::ref(run));
while (run.load())
{
// some lengthy operation
}
run.store(false);
cinThread.join();
return 0;
}
In the main While loop, I have an object of a class that is doing some lengthy operation, one which I'm trying to stop with the letter "q" coming from the user. When I type "q", i see the "run.store(false);" hit in the ReadCin method, but this doesn't break me off from the main while loop. What am I doing wrong?

Please help me to make this fake character linux device driver work

Hello I am trying to write to a fake char device driver using:
echo > /dev/
and reading it using:
cat /dev/
My problem is that I am getting continuously the first character written printed on the terminal when I do a read with the above mentioned "cat" read method after writing using the echo method above.
My aim is to get the entire set of characters written to the driver back...
I am using dynamic memory allocation for this purpose but not getting the final result after trying many ways of rewriting the code of read() and write() in the driver. Please help..
my Makefile is correct... (I am using ubuntu with a kernel version of 2.6.33...)
My code is as below:
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
static dev_t first;
static struct cdev c_dev;
static struct class *cl;
static char* k_buf = NULL;
static int my_open(struct inode *i,struct file *f)
{
printk(KERN_INFO "In driver open()\n");
return 0;
}
static int my_close(struct inode *i,struct file *f)
{
printk(KERN_INFO "In driver close()\n");
return 0;
}
static ssize_t my_read(struct file *f,char __user *buf,size_t len,loff_t *off)
{
printk(KERN_INFO "In driver read()\n");
if(k_buf == NULL)
{
printk(KERN_INFO "You cannot read before writing!\n");
return -1;
}
while(*k_buf != 'EOF')
{
if(copy_to_user(buf,k_buf,1))
return -EFAULT;
off++;
return 1;
}
return 0;
}
static ssize_t my_write(struct file *f,const char __user *buf,size_t len,loff_t *off)
{
printk(KERN_INFO "In driver write()\n");
k_buf = (char*) kmalloc(sizeof(len),GFP_KERNEL);
if(copy_from_user(k_buf,buf,len))
return -EFAULT;
off += len;
return (len);
}
static struct file_operations fops =
{
.owner = THIS_MODULE,
.open = my_open,
.release = my_close,
.read = my_read,
.write = my_write
};
static int __init rw_init(void) /*Constructor*/
{
printk(KERN_INFO "hello: rw_ch_driver registered\n");
if(alloc_chrdev_region(&first,0,1,"krishna") < 0)
{
return -1;
}
if ((cl = class_create(THIS_MODULE,"chardev")) == NULL)
{
unregister_chrdev_region(first,1);
return -1;
}
if (device_create(cl,NULL,first,NULL,"rw_char_driver") == NULL)
{
class_destroy(cl);
unregister_chrdev_region(first,1);
return -1;
}
cdev_init(&c_dev,&fops);
if(cdev_add(&c_dev,first,1) == -1)
{
device_destroy(cl,first);
class_destroy(cl);
unregister_chrdev_region(first,1);
return -1;
}
return 0;
}
static void __exit rw_exit(void)/*destructor*/
{
cdev_del(&c_dev);
device_destroy(cl,first);
class_destroy(cl);
unregister_chrdev_region(first,1);
printk(KERN_INFO "bye rw_chardriver unregistered");
}
module_init(rw_init);
module_exit(rw_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("krishna");
MODULE_DESCRIPTION("read write character driver");
Take a careful look at your while loop in my_read().
Most important note first: you don't need this loop. You've put a return statement in it, so it is never going to execute more than once, because the whole function is going to exit when the return is reached. It looks like you're trying to make the function return a single byte at a time repeatedly, but you should just call copy_to_user once, and pass it the number of bytes you want to give back to the user instead. If you only send one character at a time that's fine. It will be up to the user to make the read call again to get the next character.
The nice thing about copy_to_user, is that its return code will tell you if it failed because of bad array bounds, so there's no need to check for EOF on every character. In fact, you are not going to get 'EOF' as a character when you are reading from your buffer because it doesn't exist. Your buffer will store characters and usually a null terminator, '\0', but there is no 'EOF' character in C. EOF is a state you need to identify yourself and report to whoever called open. For the "cat" command, this is done by returning 0 from read. That being said, you should still check your array bounds so we don't end up with another Heartbleed. This SO answer has a good suggestion for how to do bounds checking to make sure you don't send more bytes than your buffer has.
Also, give [this post(https://meta.stackexchange.com/questions/981/syntax-highlighting-language-hints) a read. If you don't have your language in your question tags, it is helpful to other readers to tag your. I've edited your question to clean it up, so you can click "edit" now to see how I did it.

how do i check if execv function faild or succeeded?

i got an assignment to write a simple linux shell ,
this is the code so far :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
int main(int argc,char argv[])
{
char *token;
char command[50];
char tmp[256];
char *arg_command[]={"",0};
int pid,status,flag=0;
char *path = (char*)getenv("PATH");
while(1) // run always
{
printf("\n");
printf(getenv("PWD")); //print current dir
printf(": ");
gets(command);
if (strcmp(command,"exit")==0) //check for exit command
{
printf("bye\n");
break;
}
strcpy(tmp,path);
token = strtok(path,":");
while(token!=NULL)
{
arg_command[0] = command;
pid = fork();
if(pid>=0)
{
printf("\npid is:%d\n",pid);
if (pid==0) // child process is invoked
{
strcat(token,"/");
execv(strcat(token,command),arg_command);
exit(0);
}
else //parent process
{
wait(&status);
if(status==0)
}
}
else
{
printf("fork faild");
}
token = strtok(NULL,":");
}
if (flag == 1)
{
printf("no files or folders match this command\n");
}
strcpy(path,tmp);
}
return 0;
}
my question is how do i know whether execv was able to execute the command or not
because i want to output an error when ever the user entered a wrong command.
i also have a flag but because i cant check execv i cant use it .
Like most Unix/POSIX functions, exec* return an error code (-1) if they fail. errno will then tell you why it failed.
In fact, if they ever return, then something went wrong. Otherwise, the current process is replaced which means no code after is ever execute (exit(0) in your case).

Corrupted vector entries with LPCWSTR vector

I ahve the following piece of code. I get a correctly filled vector. But I am unable to print or use the vector contents which are file names from a directory. As soon as I do enter the first iteration. Everything gets lost. What am I doing wrong?
wprintf - This works OK
wcout-- here is where everything ends up corrupted
#include <windows.h>
#include <sstream>
#include <string>
#include <vector>
#include<iostream>
void GetAllFiles(vector<LPCWSTR>&, wstring);
using namespace std;
void main (void)
{
vector<LPCWSTR> files(0);
wstring path = L"Datasets\\Persons\\";
wstring ext = L"*.*";
wstring fullPath = path+ext;
GetAllFiles(files,fullPath);
for (unsigned i=0; i<files.size() ; i++)
{
try
{
wcout<<"::\n"<<files[i];
}
catch(exception &ex)
{
cout<<"Error:"<<ex.what();
}
}
}
void GetAllFiles(vector<LPCWSTR>& fileNames,wstring dir)
{
WIN32_FIND_DATA search_data;
memset(&search_data, 0, sizeof(WIN32_FIND_DATA));
HANDLE handle = FindFirstFile(dir.c_str(),&search_data);
while(handle != INVALID_HANDLE_VALUE)
{
wprintf(L"Found file: %s\r\n", search_data.cFileName);
fileNames.push_back(search_data.cFileName);
if(FindNextFile(handle, &search_data) == FALSE)
break;
}
}
I have attached a screen shots of the output.
search_data.cFileName is a pointer to memory controlled by the FindFirstFile/FindNextFile iterator interface; you cannot store this pointer value as the pointed-to memory could change from iteration to iteration (or even be freed after the iteration completes).
Instead, you must make a copy of the string to put in your vector, e.g. using wcsdup. Even better, define your vector as a vector<wstring>, so that push_back(search_data.cFileName); creates a wstring with the contents of search_data.cFileName.
Probably that's happening because you pass local variable to push_back(). I'm not sure here, but what could happen here:
push_back expects object of type LPCWSTR, while you passing char* instead. I don't know, how this conversion is done, but probably the pointer is just copied, and the value of this pointer becomes invalid whenyou return from the function - try explicit copying the strings before passing them to push_back.

Resources