已关闭,此问题需要更focused。目前不接受答复。
**想改善这个问题吗?**更新问题,使其仅通过editing this post关注一个问题。
2天前关闭。
Improve this question
我正在用ncurses. h和C语言构建一个基于终端的文件查看器项目。它只是一个业余爱好的附带项目,只有几行代码。我得到了一些分割错误,我甚至没有一个线索,他们在哪里,如果有人可以检查代码,我会感激很多。
#include "window.h"
#include <dirent.h>
#include <menu.h>
#include <ncurses.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static DIR *get_dir(const char *path)
{
DIR *dir;
if (strcmp(path, "current") == 0)
dir = opendir(".");
else
dir = opendir(path);
if (dir == NULL)
{
perror("Error opening dir");
exit(-1);
}
return dir;
}
WINDOW *init_window(int start_y, int start_x, int y, int x)
{
WINDOW *win;
initscr();
getmaxyx(stdscr, y, x);
cbreak();
noecho();
if (x < WDIM_X || y < WDIM_Y)
{
start_x = (x - WDIM_X_MIN);
start_y = (y - WDIM_Y_MIN);
win = newwin(WDIM_Y_MIN, WDIM_X_MIN, 1, 2);
}
else {
start_x = (x - WDIM_X) / 2;
start_y = (y - WDIM_Y) / 2;
win = newwin(WDIM_Y, WDIM_X, start_y, start_x);
}
box(win, 0, 0);
start_color();
curs_set(0);
keypad(win, true);
init_pair(1, COLOR_BLACK, COLOR_BLUE);
wbkgd(win, COLOR_PAIR(1));
wrefresh(win);
return win;
}
void delete_window(WINDOW *win)
{
delwin(win);
endwin();
}
char *get_current_dir()
{
/*
char *dirs = malloc(MAX_LENGTH * sizeof(char));
if (getcwd(dirs, sizeof(char) * MAX_LENGTH) != NULL)
return dirs;
return "Error";
*/
char *cwd = getcwd(NULL, 0);
return cwd;
}
char **dir_items(DIR *dir)
{
char **current_dirs = (char **)malloc(MAX_LENGTH * sizeof(char *));
struct dirent *entry;
int i = 0;
while ((entry = readdir(dir)) != NULL)
{
char *name = entry->d_name;
int j=i;
while (j > 0 && strcmp(name, current_dirs[j-1]) < 0)
{
current_dirs[j] = current_dirs[j-1];
j--;
}
current_dirs[j] = name;
i++;
}
return current_dirs;
}
void cd(const char *path)
{
if (chdir(path) == -1)
{
perror("Error");
}
}
void ls(const char *path)
{
DIR *dir = get_dir(path);
struct dirent *entry;
while ((entry = readdir(dir)) != NULL)
printf("%s | %s\n", path, entry->d_name);
closedir(dir);
}
static int n_elements(char **items)
{
int i = 0;
while (items[i] != NULL)
{
i++;
}
return i;
}
/* static void moveMenu(MENU *menu, WINDOW *win)
{
char c;
WINDOW *w;
while ((c = wgetch(win)) != '1')
{
switch (c)
{
case 'j':
menu_driver(menu, REQ_DOWN_ITEM);
wrefresh(win);
break;
case 'k':
menu_driver(menu, REQ_UP_ITEM);
wrefresh(win);
break;
case 'q':
delete_window(win);
exit(-1);
break;
case '\n':
delete_window(win);
win = init_window(WDIM_Y, WDIM_X, 5, 5);
cd("/");
sleep(3);
render_dir(win);
break;
}
}
} */
void render_dir(WINDOW *win)
{
char **items_chars, *titulo, c;
int i=0, x, y;
int n;
DIR *dir;
ITEM **items;
MENU *menu;
char *path = get_current_dir();
path = strcat(path, "/");
dir = get_dir(path);
items_chars = dir_items(dir);
wclear(win);
titulo = malloc(MAX_LENGTH * sizeof(char));
strcpy(titulo, get_current_dir(path));
mvwprintw(win, 0, 1, titulo);
wrefresh(win);
n = n_elements(items_chars);
items = (ITEM **)calloc(n + 1, sizeof(ITEM *));
for (int j = 0; j < n; j++)
{
items[j] = new_item(items_chars[j], "");
}
// final have to be NULL
items[n] = (ITEM *)NULL;
menu = new_menu(items);
set_menu_win(menu, win);
set_menu_sub(menu, derwin(win, 25, 40, 2, 1));
// set_menu_fore(menu, A_NORMAL);
set_menu_format(menu, 25, 1);
set_menu_back(menu, COLOR_PAIR(1));
post_menu(menu);
wrefresh(win);
while ((c = wgetch(win)) != '1')
{
switch (c)
{
case 'j':
menu_driver(menu, REQ_DOWN_ITEM);
if (i > n)
i = n;
else
i++;
//i++;
wrefresh(win);
break;
case 'k':
menu_driver(menu, REQ_UP_ITEM);
if (i < 0)
i = 0;
else
i--;
//i--;
wrefresh(win);
break;
break;
case 'q':
delete_window(win);
exit(-1);
break;
case '\n':
for (int j = 0; j < n; j++)
{
free_item(items[j]);
}
free_menu(menu);
path = strcat(path, items_chars[i]);
free(items_chars);
free(titulo);
closedir(dir);
wclear(win);
delwin(win);
getmaxyx(stdscr, y, x);
if (x < WDIM_X || y < WDIM_Y)
win = init_window(WDIM_Y_MIN, WDIM_X_MIN, 5, 5);
else
win = init_window(WDIM_Y, WDIM_X, 5, 5);
cd(path);
free(path);
mvwprintw(win, 20, 1, "s");
render_dir(win);
break;
}
}
wrefresh(win);
}
这里是主
#include "window.h"
int main(int argc, char **argv)
{
WINDOW *win;
win = init_window(WDIM_Y, WDIM_X, 5, 5);
render_dir(win);
delete_window(win);
return 0;
}
我已经尝试以各种方式释放所有内存,但它仍然存在分段错误和内存泄漏。
1条答案
按热度按时间bd1hkmkf1#
问题(或者说是一个问题,可能还有其他问题)是你正在这样做:
get_current_dir()
这样做:根据man page,
getcwd()
可以执行此操作作为POSIX.1-2001标准的扩展,如果buf为NULL,glibc的getcwd()使用malloc(3)动态分配缓冲区。在这种情况下,当buf被分配为所需的大小时,所分配的缓冲区具有长度大小,除非大小为零。调用者应该释放(3)返回的缓冲区。
因此返回的缓冲区正好是路径的大小。没有空间添加
'/'
。所以这个:
导致缓冲区溢出和未定义的行为。