gpt4 book ai didi

c - 在 C 中使用 ncurses 的 wrefresh 函数时出现段错误

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

首先,我使用 ncurses 创建两个窗口:一个用于传输,一个用于接收。基本上,一个用于编写命令,另一个用于打印命令。为了在接收窗口中写入输入,我做了一个小函数来连接接收窗口中已有的字符串和用户编写的字符串(我认为问题就在那里)。

因此,当我运行代码时,程序失败并显示在 wrefresh(winReception); 行转储的段错误代码

但奇怪的是,如果输入的字符数为 7 个或更少,则可以正常工作,如果输入的字符数为 8 或更多,则无法正常工作。

我正在使用 Code::Blocks

屏幕截图:https://imgur.com/a/zEwBs1k

这是一些代码:

//Global variables
WINDOW * winReception;
WINDOW * winTransmission;
char * command;
char mesg[] = "Enter a command";
//variable to stock the input in reception window
char *textinwindow = "";

//main
int main(int argc, char* argv[])
{
initscr();

/* WINDOW RECEPTION */
winReception = newwin(15, 0, 0, 0);
wrefresh(winReception);


/* WINDOW TRANSMISSION*/
winTransmission= newwin(8, 0, 15, 0);
wrefresh(winTransmission);
mvwprintw(winTransmission, 1, 2, mesg);

wgetstr(winTransmission, &command);
verifInput(&command);

free(textinwindow);

exit(0);
}

//concat function (where I think the bug is)
char* concat(char *s1, char *s2)
{
char *result = (char *) malloc(strlen(s1) + strlen(s2) + 1);
strcpy(result, s1);
strcat(result, "\n ");
strcat(result, s2);

return result;
}

//verifInput (where the program fails)
void verifInput (char* cmd)
{
/* WINDOW RECEPTION */
textinwindow = concat(textinwindow, cmd);
mvwprintw(winReception, 1, 2, textinwindow);
wrefresh(winReception);

/* WINDOW TRANSMISSION*/
touchwin(winTransmission);
wclear(winTransmission);
wrefresh(winTransmission); //Program fails here
mvwprintw(winTransmission, 1, 2, mesg);

wgetstr(winTransmission, &command);
verifInput(&command);
}

最佳答案

如评论中所述,这里存在许多问题,但主要的问题是 wgetstr() 的使用完全错误,因为它接受用户的输入并将其填充到缓冲区中,但你还没有分配缓冲区。我们不知道 command 的值是什么,因此它将数据存储到随机内存中。

解决此问题的错误方法是:

char command[256];
wgetstr(winTransmission, command); // NO

因为虽然您提供了一个存储用户输入的位置,但 wgetstr() 不知道缓冲区有多大,如果用户输入太多,它就会覆盖内存也在那里。不好。

相反,我们将使用带有缓冲区和计数的有界版本wgetnstr()

char command[256];
wgetnstr(winTransmission, command, sizeof command); // YES

现在它永远不会覆盖缓冲区!

其他问题:虽然您在代码末尾释放了 textinwindow 内存,但每次调用 concat() 时,旧的 textinwindow 的值(也分配了内存)被丢弃。这肯定是内存泄漏。

最后,一个微妙的问题。由于 mvwprintw() 采用 printf 样式格式字符串,因此您传递给它的值来自用户,并且可能包含 %s 标记。这不会带来任何好处。相反:

    mvwprintw(winReception, 1, 2, "%s", textinwindow);

这意味着用户输入字符串中的任何时髦 % 都不会造成严重破坏。

这是我想到的:

#include <stdio.h>
#include <ncurses.h>
#include <string.h>
#include <stdlib.h>

//Global variables
WINDOW * winReception;
WINDOW * winTransmission;

char command[256];

const char mesg[] = "Enter a command";
//variable to stock the input in reception window
char *textinwindow = 0;

void verifInput (const char* cmd);

//main
int main(int argc, char* argv[])
{
initscr();

/* WINDOW RECEPTION */
winReception = newwin(15, 0, 0, 0);
wrefresh(winReception);


/* WINDOW TRANSMISSION*/
winTransmission= newwin(8, 0, 15, 0);
wrefresh(winTransmission);
mvwprintw(winTransmission, 1, 2, mesg);

wgetnstr(winTransmission, command, sizeof command);
verifInput(command);

free(textinwindow);

exit(0);
}

//concat function (where I think the bug is)
char* concat(const char *s1, const char *s2)
{
// 2 = newline + space
// 1 = final NUL byte
char *result = (char *) malloc(strlen(s1) + 2 + strlen(s2) + 1);
strcpy(result, s1);
strcat(result, "\n ");
strcat(result, s2);

return result;
}

//verifInput (where the program fails)
void verifInput (const char* cmd)
{

// free up old memory except for the first time
if (textinwindow == 0)
textinwindow = concat("", cmd);
else
{
char *save = textinwindow;
textinwindow = concat(textinwindow, cmd);
free(save);
}

/* WINDOW RECEPTION */
mvwprintw(winReception, 1, 2, "%s", textinwindow);
wrefresh(winReception);

/* WINDOW TRANSMISSION*/
touchwin(winTransmission);
wclear(winTransmission);
wrefresh(winTransmission); //Program fails here
mvwprintw(winTransmission, 1, 2, mesg);

wgetnstr(winTransmission, command, sizeof command);
verifInput(command);
}

关于c - 在 C 中使用 ncurses 的 wrefresh 函数时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58793504/

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