通过valgrind运行程序时遇到错误,我已经在其他任何与此主题有关的帖子中寻找解决方案。
我的程序假设模拟一个Linux终端,当我尝试运行一个简单的命令,例如“ echo hello world”时,我得到以下信息:
==21569== Invalid write of size 8
==21569== at 0x108FDF: getInput (in /home/sahar/Desktop/ex1/ex1)
==21569== by 0x108B95: main (in /home/sahar/Desktop/ex1/ex1)
==21569== Address 0x52324c0 is 0 bytes after a block of size 32 alloc'd
==21569== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21569== by 0x108D2F: getInput (in /home/sahar/Desktop/ex1/ex1)
==21569== by 0x108B95: main (in /home/sahar/Desktop/ex1/ex1)
==21569==
==21570== Syscall param execve(argv) points to uninitialised byte(s)
==21570== at 0x4F20E37: execve (syscall-template.S:78)
==21570== by 0x4F21732: execvpe (execvpe.c:138)
==21570== by 0x109053: execute (in /home/sahar/Desktop/ex1/ex1)
==21570== by 0x108BA5: main (in /home/sahar/Desktop/ex1/ex1)
==21570== Address 0x52324b8 is 24 bytes inside a block of size 32 alloc'd
==21570== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21570== by 0x108D2F: getInput (in /home/sahar/Desktop/ex1/ex1)
==21570== by 0x108B95: main (in /home/sahar/Desktop/ex1/ex1)
==21570==
hello world
我的代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <pwd.h>
#define MAXCOM 510 // max number of letters in a command
void printDirectory();
char** getInput();
int countWords(char *str);
void execute(char** command);
void freeCommand(char ** cmd);
int countCmd=0, cmdLength=0; //global
int main()
{
while(1)
{
printDirectory();
char** command = getInput();
execute(command);
freeCommand(command);
}
}
//Function to print the current directory
void printDirectory()
{
char cwd[200];
getcwd(cwd, sizeof(cwd));
struct passwd *pw = getpwuid(getuid());
const char *username = pw->pw_name;
printf("%s@%s>", username,cwd);
}
//Function to get input from the user
char** getInput()
{
char command[MAXCOM];
char *word;
char **cmdArr;
char done[]="done", cd[]="cd"; //specific cases
if(fgets(command,MAXCOM,stdin)==NULL)
strcpy(command," "); //empty string
cmdLength=cmdLength+strlen(command);
char *pos;
if ((pos=strchr(command, '\n')) != NULL) //deleting \n
*pos = '\0';
int numOfWords = countWords(command);
countCmd++;
cmdArr = malloc((numOfWords+1) * sizeof(char*));
if(cmdArr == NULL)
{
printf("ERR");
freeCommand(cmdArr);
exit(1);
}
//dealing with the first word at the string
word = strtok(command, " ");
cmdArr[0] = malloc((strlen(word)+1) * sizeof(char));
if(cmdArr[0] == NULL)
{
printf("ERR");
freeCommand(cmdArr);
exit(1);
}
strcpy(cmdArr[0], word);
//checking if done
if(strcmp(done,cmdArr[0]) == 0)
{
printf("Num of commands: %d\n",countCmd);
printf("Total length of all commands: %d\n",cmdLength);
printf("Average length of all commands: %f\n",(double)((double)cmdLength/(double)countCmd));
printf("See you Next time !\n");
exit(0);
}
//cd command undefined yet
if(strcmp(cd, cmdArr[0]) == 0)
{
printf("Comand not supperted (Yet)\n");
main();
}
//dealing with the rest of the string
for(int i=1 ; i<numOfWords ; i++)
{
word = strtok(NULL, " ");
cmdArr[i] = malloc((strlen(word)+1) * sizeof(char));
if(cmdArr[i] == NULL)
{
printf("ERR");
freeCommand(cmdArr);
exit(1);
}
strcpy(cmdArr[i],word);
}
cmdArr[numOfWords+1]=(char *) NULL; //last value is NULL
return cmdArr;
}
void execute(char** command)
{
// Forking a child
pid_t pid = fork();
if (pid == -1) {
printf("ERR");
return;
}
else if (pid == 0) {
if (execvp(command[0], command) < 0) {
//printf("Could not execute command...\n");
exit(0);
}
exit(0);
} else {
// waiting for child to finish
wait(NULL);
return;
}
}
int countWords(char *str)
{
int state = 0;
int words = 0; //word count
while (*str)
{
//if next character is a separator, changeing the state to OUT
if (*str == ' ' || *str == '\n' || *str == '\t')
state = 0;
//if next character is not a separator and state is OUT- set the state to IN and increment word count
else if (state == 0)
{
state = 1;
++words;
}
//next character
++str;
}
return words;
}
void freeCommand(char ** cmd)
{
int i=0;
if(cmd!=NULL && getpid==0) //only child can free the allocated memory
{
while(cmd[i]!=NULL){
free(cmd[i]);
i++;
}
}
free(cmd);
}
我已经检查了我的malloc函数很多次了,无法弄清楚问题出在哪里...知道吗?谢谢。
答案 0 :(得分:1)
我认为您的问题在这里:
cmdArr = malloc((numOfWords+1) * sizeof(char*));
...
cmdArr[numOfWords+1]=(char *) NULL; //last value is NULL
您需要
cmdArr[numOfWords]=(char *) NULL;