所以我正在嘗試制作一個 shell 實作,它似乎作業得很好。除了有一個非常奇怪的問題。輸入命令“/bin/ls -l /usr/include”后出現這些錯誤:
錯誤 1:
a.out: malloc.c:2379: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' 失敗。中止(核心轉儲)
錯誤 2:
realloc(): 無效指標中止(核心轉儲)
我的代碼:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
char **parse_cmdline( const char *cmdline )
{
int token_count = 1;
for(int i = 0; cmdline[i] != '\0';i )
{
if(cmdline[i] == ' ')
{
token_count ;
}
}
char *token = strtok((char*)cmdline, " ");
char **arr = malloc(token_count 1);
int i;
for(i = 0;token != NULL;i )
{
arr[i] = token;
token = strtok(NULL, " ");
}
arr[i] = NULL; // make last element NULL for execvp() to work properly
return arr;
}
int main(void)
{
int fd = 0; // set read() to read from STDIN_FILENO, because it's number is 0
const size_t read_size = 1; // set chunk size
size_t size = read_size;
char *buff = malloc(size 1);
size_t offset = 0;
size_t res = 0;
write(STDOUT_FILENO, "$ ", strlen("$ "));
while((res = read(fd, buff offset, read_size)) > 0) // read from stdin and save to buff
{
if(res == -1)
{
//read_error();
free(buff);
}
if(buff[offset] == '\n')
{
buff[offset] = '\0';
char **result = parse_cmdline(buff);
if(result[0] != NULL)
{
int exec;
int status;
pid_t pid = fork();
if(pid == -1)
{
//fork_error();
}
else if(pid == 0) // Handle child process
{
if((exec = execvp(result[0], result)) == -1)
{
//file_error(result[0]);
}
}
else
{
waitpid(pid, &status, 0);
}
offset = 0;
free(buff);
buff = malloc(size 1);
size = read_size;
}
free(result);
result = NULL;
write(STDOUT_FILENO, "$ ", strlen("$ "));
}
else
{
offset = res;
buff[offset] = '\0';
if (offset read_size > size)
{
size *= 2;
buff = realloc(buff, size 1);
}
}
}
free(buff);
return 0;
}
下面是如何重現錯誤 1: 啟動程式,第一個輸入應該是:“/bin/ls -l /usr/include”。之后按回車,然后輸入任何命令或只是一個空行,就會出現錯誤。
如何重現錯誤 2: 啟動程式并運行任何命令。然后運行“/bin/ls -l /usr/include”,然后運行其他2個命令,就會出現錯誤。
注意:使用 Oracle VM VirtualBox 進行編譯:
gcc -Wall -pedantic -std=c11 file.c
./a.out
uj5u.com熱心網友回復:
char **arr = malloc(token_count 1);沒有分配足夠的空間。因為沒有分配足夠的空間,試圖用token_count 1指標填充它會超出分配的空間并破壞記憶體中的其他資料。
malloc分配多個位元組,而不是多個元素。它不知道您嘗試分配的元素的大小。因此,您必須始終告訴它要分配的總位元組數。您可以通過將要分配的事物數量乘以每個事物的大小來做到這一點。
適用的一般模式malloc是:
SomeType *p = malloc(NumberOfThings * sizeof *p);
之所以有效,*p是因為它是記憶體將包含的物件之一,并sizeof *p產生此類物件所需的位元組數。因此,在這種情況下,您可以使用:
char **arr = malloc((token_count 1) * sizeof *arr);
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/400202.html
下一篇:在shell中將變數值減1
