我一直试图找出我的程序生成细分的地方都无济于事。 我需要帮助指向哪些字符串操作或char指针在运行时导致分段错误。程序编译成功但在运行时出现分段错误。
#include<curses.h>
#include<strings.h>
#include<unistd.h>
#include<stdlib.h>
/*Implements a Scrolling headband that takes a string argument and continously scrolls*/
int main(int argc, char* argv[])
{
/*A Substring function to return substring of a string*/
char *substr(const char *src, int start, int len);
/*Appends a character to the Given string*/
void append(char* s, char c);
/***Check if the argument is invalid***/
if(argc!=2)
{
puts("Invalid number of arguments: Usage:headband <String>");
}
/**Get headtext from the string argument argv[1]**/
char *headtext = argv[1];
/*headband(headtext);*/
/*temporary variable to store strings as execution progresses*/
char temp[100];
/*Counter for streaming and scolling headband text*/
int count = 0;
/*Placeholder for temporary headband text*/
char hold[100];
int i;
/*maximum x and y co-ordinates of the Screen*/
int max_x,max_y;
/*Initialize screen for ncurses*/
initscr();
/*Don't show cursor*/
curs_set(0);
/*Get terminal console dimensions*/
getmaxyx(stdscr, max_y, max_x);
/*Get console width set to default console screen width=80*/
int consolewidth = max_x;
/*Clear the screen*/
clear();
/*Set the first value as end of String for the momment*/
temp[0] = '\0';
/*Run this loop continuously to keep scrolling*/
for (;;)
{
for(i=0; i < strlen(headtext); i++)
{
count++;
/*Append headband text character by character to string hold*/
append(temp, headtext[i]);
move(0,consolewidth - count);
if (consolewidth - count > 0)
{
mvaddstr(0,console_width-count,temp);
refresh();
}
else if (consolewidth - count == 0)
{
strcpy(hold, temp);
char q;
int com = i;
for(;;)
{
/*Scroll text by triming one character at a time*/
/*from the left, then adding that character to the*/
/*right side of the text*/
com = com + 1;
if (com < strlen(headtext))
{
q = headtext[com];
}
else
{
com = 0;
q = headtext[com];
//q = hold[0];
}
strcpy(hold, substr(hold, 1, strlen(hold) - 1));
append(hold, q);
move(0,0);
clear();
mvaddstr(0,0,hold);
refresh();
usleep(50);
}
}
usleep(50);
}
}
return 0;
}
/*A Substring function to return substring of a string*/
char * substr(const char *src, int start, int len)
{
char *dest = malloc(len+1);
if (dest)
{
memcpy(dest, src+start, len);
dest[len] = '\0';
}
return dest;
}
/*Appends a character to the Given string*/
void append(char s[], char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = '\0';
}
答案 0 :(得分:1)
使用手动调试方法;
#define DEBUG(A) fprintf(stderr, "%d step\n", (A))
#define PRINT(A) fprintf(stderr, "%s\n", (A))
#include<curses.h>
#include <strings.h>
#include<unistd.h>
#include<stdlib.h>
int main(int argc, char* argv[]){
char *substr(const char *src, int start, int len);
PRINT("at top of the main" ) ; /***/
DEBUG(1);
void append(char* s, char c);
if(argc!=2)
{
puts("Invalid number of arguments: Usage:headband <String>");
}
char *headtext = argv[1];
DEBUG (2);
char temp[100];
int count = 0;
char hold[100];
int i;
int max_x,max_y;
initscr();
DEBUG (3);
curs_set(0);
getmaxyx(stdscr, max_y, max_x);
DEBUG (4);
int consolewidth = max_x;
clear();
DEBUG(5);
temp[0] = '\0';
for (;;)
{
for(i=0; i < strlen(headtext); i++)
{
count++;
append(temp, headtext[i]);
DEBUG(6);
move(0,consolewidth - count);
DEBUG(7);
if (consolewidth - count > 0)
{
mvaddstr(0,console_width-count,temp);
refresh();
}
else if (consolewidth - count == 0)
{
char q;
int com = i;
strcpy(hold, temp);
for(;;)
{
com = com + 1;
if (com < strlen(headtext)){
q = headtext[com];
DEBUG (10);
}else{
com = 0;
q = headtext[com];
//q = hold[0];
}
strcpy(hold, substr(hold, 1, strlen(hold) - 1));
append(hold, q);
move(0,0);
clear();
mvaddstr(0,0,hold);
refresh();
usleep(50);
}
}
usleep(50);
}
}
return 0;
}
char *
substr(const char *src, int start, int len)
{
char *dest = malloc(len+1);
PRINT ( "in substr" );
if (dest)
{
memcpy(dest, src+start, len);
dest[len] = '\0';
}
PRINT ("at the end of the sub);
return dest;
}
void append(char s[], char c)
{
int len = strlen(s);
PRINT( "in append function" );
s[len] = c;
s[len+1] = '\0';
PRINT ( "at the end of the append function" );
}
编译它,然后你可以很容易地看到你在哪里采取分段错误
答案 1 :(得分:1)
我不知道您使用的是哪种编译器,但这里有一个如何使用GCC和GDB进行调试的快速指南:
$ gcc -g file.c -o myexec # the -g flag enables debug info
$ gdb ./myexec
现在您处于GDB提示符下。如果需要设置命令行参数,请使用:
set args <arg1> <arg2> ...
然后运行你的程序
run
一旦崩溃,你可以做各种各样的事情。它还显示程序中您的错误发生在哪一点。您可能想要使用这些命令:
bt # prints the backtrace / call stack
print <expr> # print value of an expression
有几个cheat sheets on the web,因此您可以快速了解可用的命令类型。
答案 2 :(得分:0)
我看到的最明显的问题可能导致分段错误,如下代码所示:
if(argc!=2)
{
puts("Invalid number of arguments: Usage:headband <String>");
}
char *headtext = argv[1];
在确定提供了无效数量的参数后,继续分配指向argv[1]
的指针。如果用户未提供 参数,则结果会将NULL
传递给strlen()
。这导致未定义的行为,并且strlen(NULL)
通常在Linux \ Unix上崩溃。在我的简短测试中,提供 参数确实导致滚动头带没有任何崩溃。
您可以考虑将代码更改为类似以下内容:
if(argc<2)
{
puts("Invalid number of arguments: Usage:headband <String>");
exit(EXIT_FAILURE);
}
char *headtext = argv[1];
<强>更新强>
看来你的当前代码是不必要的复杂(例如嵌套的无限循环),我相信它的预期目的。目前形式的代码也存在一些问题需要解决。 malloc()
函数中对substr()
的调用产生memory leak,随后丢失指向已分配内存的指针。如果用户提供的文本大于temp[100]
缓冲区的大小,则会在append()
函数中溢出缓冲区。由于长度不会改变,因此也不必多次计算headtext
的长度。
我认为应该在raw terminal escape codes上使用 curses 。 curses 库实际上是原始终端代码的包装器,并提供灵活高效的API,以便应用程序无需担心底层终端功能。也许NCURSES Programming HOWTO或X/Open Curses, Reference Pages可能有用。
我自己不是 curses 专家,但是,以下示例显示了另一种基于curses的方法,该方法基于原始代码并且看起来具有相同的输出 * :
#include<curses.h>
#include<signal.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
/* maximum x and y co-ordinates of the window */
int max_x, max_y;
/* pointer to headband buffer */
char * headband = NULL;
/* counter for streaming and scolling headband text */
unsigned int count;
/* Handler for window resize */
void handle_winch(int sig)
{
/* Function for initializing curses & headband buffer */
void my_init();
/* Disable signal handler during reinitialization */
signal(SIGWINCH, SIG_IGN);
/* Reinitialize the window to update data structures */
endwin();
my_init();
}
/* Function for initializing curses & headband buffer */
void my_init()
{
/* Initialize / Reinitialize screen for ncurses */
initscr();
curs_set(0);
clear();
refresh();
getmaxyx(stdscr, max_y, max_x);
/* Allocate / Reallocate and initialize scrolling headband buffer */
free(headband);
headband = (char *)malloc(max_x+1);
memset(headband, ' ', max_x);
headband[max_x] = '\0';
count = 0;
/* Setup signal handler for window resizing */
signal(SIGWINCH, handle_winch);
}
/* Implements a scrolling headband that takes a
* string argument and scrolls continously */
int main(int argc, char* argv[])
{
char * headtext;
int headtext_len;
int size;
if(argc<2)
{
puts("Invalid number of arguments: Usage:headband <String>");
exit(EXIT_FAILURE);
}
/* Get headtext from the argument argv[1] and compute length */
headtext = argv[1];
headtext_len = strlen(headtext);
/* Call common initialization / reinitialization routine */
my_init();
/* Run this loop continuously to keep scrolling */
for(;;)
{
/* Store & use copy of max_x in case original max_x is
* modified in signal handler by window resize event */
size = max_x;
/* Rotate headband by shifting entire buffer and then
* appending next character from headtext buffer */
memmove(&headband[0], &headband[1], size-1);
headband[size-1] = headtext[count++ % headtext_len];
/* Update window */
move(0,0);
mvaddstr(0,0,headband);
refresh();
usleep(50000);
}
/* Unreachable, but included for completeness */
endwin();
free(headband);
exit(EXIT_SUCCESS);
}
*包括窗口调整大小处理