gpt4 book ai didi

c - 用 c 编写我自己的 shell - free() 导致问题

转载 作者:行者123 更新时间:2023-11-30 16:08:18 25 4
gpt4 key购买 nike

我正在尝试编写自己的 shell,但有些东西无法与分配和空闲一起使用。我一遍又一遍地检查我的代码,我无法理解为什么我的自由函数给我带来了问题......当我不使用它时,一切正常,但是当我使用它时,代码在第二次迭代后停止工作。 ..我非常感谢您的帮助...

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <limits.h> //for PATH_MAX - longest path name permited in linux
#include <sys/wait.h>
#include <fcntl.h>

typedef struct{
char **parametersArray; //this array contains the command and the parameters
int size_of_array; //the number of strings in the array
int toFileFlag; //if we wnat to write to file
char *toFile; //name of file to write to
int fromFileFlag;//if we wnat to read from file
char *fromFile; //name of file to read to
}UserInput;

int runInBackground = 0; //is command running in background? if so, runInBackground=1;

//********************************************************************************************************************
//functions list:

UserInput* inputTokenization(char *a); //recieve string of the user input, and returns pointer to struct of UserInput.
void execCommand(UserInput *user_input); //exec the requestd command with the parameters given
void free_All_Allocations(UserInput *userinput);

//*******************************************************************************************************************
int main(int argc, char *argv[])
{
char userInputTxt[LINE_MAX]; //the line the user enters (hopefully command+parameters)
UserInput *u_i;
int i = 0;

while(1)
{
i = 0;
printf("\033[1;35m"); //print in with color (purple)
printf("### "); //### is the prompt I chose
fflush(stdout);
memset(userInputTxt, 0, LINE_MAX); //cleaning array from previous iteration
read(0, userInputTxt, LINE_MAX);

if(strcmp(userInputTxt, "exit\n") == 0) //exit the program if the user enters "exit"
exit(EXIT_SUCCESS);

u_i = inputTokenization(userInputTxt); //parsing the char array userInputTxt
execCommand(u_i);
free_All_Allocations(u_i);
}

}

UserInput* inputTokenization(char *a)
{
int i=0, size;
size = strlen(a);
UserInput *user_input = (UserInput*)malloc(sizeof(UserInput)*1);
if(user_input == NULL)
{
perror("failed to allocate memory");
exit(EXIT_FAILURE);
}


user_input->fromFileFlag = 0;
user_input->toFileFlag = 0;
user_input->size_of_array = 2;

//counting how many token we have
while(i<size)
{
if(a[i] == ' ')
(user_input->size_of_array)++;
if (a[i] != '<' || a[i] != '>' )
break;
i++;
}
printf("%d\n", user_input->size_of_array);

//we don't want to change original array(a), so we'll copy a to tmp and use tmp
char *tmp = (char*)malloc(size+1);
if(tmp == NULL)
{
perror("failed to allocate memory");
exit(EXIT_FAILURE);
}
strncpy(tmp, a, size-1);

//we'll allocate array of arrays. It's size: number of tokens in the original array, even though we might not use all of it-
//some tokens might be name of file to read or write to
user_input->parametersArray = (char**)malloc(user_input->size_of_array);
if(user_input->parametersArray == NULL)
{
perror("failed to allocate memory");
exit(EXIT_FAILURE);
}

i=0;
char* token = strtok(tmp, " ");
user_input->parametersArray[i] = (char*)malloc(strlen(token)+1);
if(user_input->parametersArray[i] == NULL)
{
perror("failed to allocate memory");
exit(EXIT_FAILURE);
}
strcpy(user_input->parametersArray[i], token);
i++;

while(token != NULL)
{
token = strtok(NULL, " ");
if(token !=NULL)
{
if(strcmp(token, "<") != 0 && strcmp(token, ">") !=0 && strcmp(token, "&") != 0)
{
user_input->parametersArray[i] = (char*)malloc(strlen(token)+1);
if(user_input->parametersArray[i] == NULL)
{
perror("failed to allocate memory");
exit(EXIT_FAILURE);
}
strcpy(user_input->parametersArray[i], token);
i++;
continue;
}

if(strcmp(token, "<") == 0)
{
user_input->fromFileFlag = 1;
token = strtok(NULL, " ");
if(token !=NULL)
{
user_input->fromFile = (char*)malloc(strlen(token)+1);
if(user_input->fromFile == NULL)
{
perror("failed to allocate memory");
exit(EXIT_FAILURE);
}
strcpy(user_input->fromFile, token);
}
}

if(strcmp(token, ">") == 0)
{
user_input->toFileFlag = 1;
token = strtok(NULL, " ");
if(token != NULL)
{
user_input->toFile = (char*)malloc(strlen(token)+1);
if(user_input->toFile == NULL)
{
perror("failed to allocate memory");
exit(EXIT_FAILURE);
}
strcpy(user_input->toFile, token);
}
}
if(strcmp(token, "&") == 0)
{
runInBackground = 1;
break;
}

}
}

user_input->parametersArray[i] = NULL;

free(tmp);
return user_input;
}

void execCommand(UserInput *user_input)
{
pid_t pid;
int status;

pid = fork();

if(pid == -1) //fork failed
{
perror("fork() failed");
exit(EXIT_FAILURE);
}
if(pid == 0) //child process
{
if(user_input->fromFileFlag == 1) //if we have file to read from
{
close(0);
if(open(user_input->fromFile, O_RDONLY) == -1)
{
perror("open file to read failed");
exit(EXIT_FAILURE);
}
}
if(user_input->toFileFlag == 1) //if we have file to write to
{
close(1);
if(open(user_input->toFile, O_WRONLY | O_CREAT, 0766) == -1)
{
perror("open file to write failed");
exit(EXIT_FAILURE);
}
}

if(execvp(user_input->parametersArray[0], user_input->parametersArray) == -1)
{
perror("execvp() failed");
exit(EXIT_FAILURE);
}
}

if(runInBackground == 0) //as long as this is the only command to execute,
waitpid(pid, &status, 0); //wait until chile process (execvp) finish. Otherwise, father process go again, and chile process run in background
}

void free_All_Allocations(UserInput *userinput)
{
int i=0;

while(userinput->parametersArray[i] != NULL)
{
free(userinput->parametersArray[i]);
i++;
}

free(userinput->parametersArray);
if(userinput->fromFileFlag == 1)
free(userinput->fromFile);
if(userinput->toFileFlag == 1)
free(userinput->toFile);
free(userinput);
}

最佳答案

我建议使用valgrind

使用标志 -ggdb3 编译您的代码,然后使用您的程序执行 valgrind。它会显示程序执行期间所有无效的读取和写入。不仅如此,它还会准确地告诉您它们发生在哪一行以及相应的函数调用跟踪。

This question如果您是 valgrind 的初学者,这是一个很好的起点。

关于c - 用 c 编写我自己的 shell - free() 导致问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59382565/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com