c - Valgrind 说 - 大小为 8 的无效写入
问题描述
通过 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 函数,但无法弄清楚问题是什么……知道吗?谢谢。
解决方案
我认为你的问题在这里:
cmdArr = malloc((numOfWords+1) * sizeof(char*));
...
cmdArr[numOfWords+1]=(char *) NULL; //last value is NULL
你需要
cmdArr[numOfWords]=(char *) NULL;
推荐阅读
- c# - 使用 IHttpclientFactory 获取令牌
- matlab - 我应该使用哪两种元启发式技术在 MATLAB 中构建用于脑肿瘤检测的混合算法?
- quartus - 在 Eclipse 中更改代码后“未找到 Nios II 目标连接路径”
- azure-functions - 发生错误:SQL Server 的 ODBC 驱动程序 17]通信链路故障 (0) (SQLExecDirectW)'
- bootstrap-4 - 媒体查询在 Bootstrap 断点上不起作用
- angular - 如何在 Angular 应用程序中托管 MVC 应用程序并将令牌从 Angular 传递到 MVC 应用程序
- java - 在数组中查找不重复的最大 GCD 和
- salesforce - 将用户添加到社区
- php - 如何在wordpress中访问MySQL数据库
- python - 使用 selenium 查找站点上其他地方使用的具有多个类的 div。(Python)