2014-12-26 32 views
0

我写了一段代码,该代码应该是一个字符数组,并使其看起来像是计算机正在输入文本。很简单,对吗?但是,当我跑了,终端告诉我:Stack Smashing/BackTrace

*** stack smashing detected ***: ./TYPE terminated 
======= Backtrace: ========= 
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x45)[0xb759aeb5] 
/lib/i386-linux-gnu/libc.so.6(+0x104e6a)[0xb759ae6a] 
./TYPE[0x80486a9] 
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb74af4d3] 
./TYPE[0x8048591] 
======= Memory map: ======== 
08048000-08049000 r-xp 00000000 08:01 1580147 /home/jeremy/Desktop/programming/cpp/Jumping into C++/TYPE 
08049000-0804a000 r--p 00000000 08:01 1580147 /home/jeremy/Desktop/programming/cpp/Jumping into C++/TYPE 
0804a000-0804b000 rw-p 00001000 08:01 1580147 /home/jeremy/Desktop/programming/cpp/Jumping into C++/TYPE 
08a30000-08a51000 rw-p 00000000 00:00 0   [heap] 
b7449000-b744b000 rw-p 00000000 00:00 0 
b744b000-b7467000 r-xp 00000000 08:01 4195157 /lib/i386-linux-gnu/libgcc_s.so.1 
b7467000-b7468000 r--p 0001b000 08:01 4195157 /lib/i386-linux-gnu/libgcc_s.so.1 
b7468000-b7469000 rw-p 0001c000 08:01 4195157 /lib/i386-linux-gnu/libgcc_s.so.1 
b7469000-b7493000 r-xp 00000000 08:01 4198259 /lib/i386-linux-gnu/libm-2.15.so 
b7493000-b7494000 r--p 00029000 08:01 4198259 /lib/i386-linux-gnu/libm-2.15.so 
b7494000-b7495000 rw-p 0002a000 08:01 4198259 /lib/i386-linux-gnu/libm-2.15.so 
b7495000-b7496000 rw-p 00000000 00:00 0 
b7496000-b763a000 r-xp 00000000 08:01 4198264 /lib/i386-linux-gnu/libc-2.15.so 
b763a000-b763c000 r--p 001a4000 08:01 4198264 /lib/i386-linux-gnu/libc-2.15.so 
b763c000-b763d000 rw-p 001a6000 08:01 4198264 /lib/i386-linux-gnu/libc-2.15.so 
b763d000-b7640000 rw-p 00000000 00:00 0 
b7640000-b7718000 r-xp 00000000 08:01 8786914 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16 
b7718000-b7719000 ---p 000d8000 08:01 8786914 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16 
b7719000-b771d000 r--p 000d8000 08:01 8786914 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16 
b771d000-b771e000 rw-p 000dc000 08:01 8786914 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16 
b771e000-b7725000 rw-p 00000000 00:00 0 
b773e000-b7742000 rw-p 00000000 00:00 0 
b7742000-b7743000 r-xp 00000000 00:00 0   [vdso] 
b7743000-b7763000 r-xp 00000000 08:01 4198254 /lib/i386-linux-gnu/ld-2.15.so 
b7763000-b7764000 r--p 0001f000 08:01 4198254 /lib/i386-linux-gnu/ld-2.15.so 
b7764000-b7765000 rw-p 00020000 08:01 4198254 /lib/i386-linux-gnu/ld-2.15.so 
bffc0000-bffe1000 rw-p 00000000 00:00 0   [stack] 
abcdefghijklmnopqrstuvwxyzAborted (core dumped) 

我是新的C++(我有一个C的背景),我不知道什么栈粉碎或回溯跟踪。如果你能帮助我,它会有很大帮助!下面是代码:

#include <iostream> 
#include <ctime> 
#include <cstdlib> 
#include <unistd.h> 

using namespace std; 

void type(char letters[]); 

int main(){ 

    char letters[27] = "abcdefghijklmnopqrstuvwxyz"; 
    system("clear"); 
    type(letters); 

    return 0; 
} 

void type(char letters[]){ 

    unsigned int wait = 30000000; 

    system("clear"); 
    for(int i = 0; letters[i] != '\n'; i++){ 
     usleep(wait) 
     cout << letters[i]; 
    } 

} 
+0

你正在寻找一个\ n表示不存在;字符串以null结尾。 – antlersoft

+0

因此,如果我设置字母[27] ='\ n',那么它会解决吗? – DarkSun

+0

当您读取或写入堆栈之外并且您(应该)知道现代C和C++编译器上的所有局部变量都存储在堆栈中时,碎片化堆栈是。如果你曾经使用调试器,那么你应该知道什么是回溯,这是函数调用堆栈。 –

回答

1

你是一个无限循环

您正在寻找'\n'不存在。您应该查找空字符\0

for(int i = 0; letters[i] != '\0'; ++i){ 
    usleep(wait) 
    cout << letters[i]; 
} 
+0

除了现在阵列的长度应该是28 – antlersoft

+0

...并且添加的硬终端是无用的。该字符串的末尾已经存在一个。在给定原始输入字符串的情况下,查找空字符而不是“\ n”的建议是正确的。 – WhozCraig

+0

谢谢。我纠正了我的答案 –

0

您可以在此处使用的两种解决方案之一。

1)你可以在循环中包含\ n,但是它必须在数组本身中,数组的大小必须增加1到字母[28]。

2)你守阵,你声明,但for循环将

for(int i = 0; letters[i]; i++){ 
    cout << letters[i]; 
} 

第二个解决方案,你不会有改变数组的大小和循环将持续到年底的数组

2

C++中的字符串预计为空终止,即它们的最后一个字符是\0。在您的代码中,循环不会终止在字符串letters的末尾,因为您正在寻找\n字符,该字符实际上并不存在于该字符串中。

首先修复

终止与你正在寻找在循环的字符的字符串:

char letters[28] = "abcdefghijklmnopqrstuvwxyz\n"; 

其次修复

通过寻找年底终止循环实际上确实存在的字符串字符\0

for(int i = 0; letters[i] != '\0'; i++) 

第三修复

使用适当的string length支票的循环终止条件:

int len = strlen(letters); 
for(int i = 0; i < len; i++) 

或者那些三者的任意组合。

一般来说,将字符串声明为固定大小的数组绝不是一个好主意,所以请改用const char *letters = "...";

0

除了其他评论者注意到的字符串末尾问题之外,由于您使用的是cout,因此您的代码可能不会给您所需的效果。该输出流会缓存内容,直到您发送新行,这样在打印最终换行时,您的“打字”将一次显示。

您可以通过打印到cerr或在应打印每个字符后通过清除cout来获得一个一字符的时间效果。

0

如果您使用的是C++,则应该使用std::string。这将跟踪你的长度,但你也可以使用迭代器。

#include <iostream> 
#include <ctime> 
#include <cstdlib> 
#include <unistd.h> 

using namespace std; 

void type(const string &); 

int main(){ 

    string letters = "abcdefghijklmnopqrstuvwxyz"; 
    system("clear"); 
    type(letters); 

    return 0; 
} 

void type(const string &letters) 
{ 
    unsigned int wait = 30000000; 

    system("clear"); 
    for(string::const_iterator it = letters.begin(); it != letters.end(); it++) 
    { 
     usleep(wait) 
     cout << *it; 
    } 
} 

尽管如此,如果你愿意,你仍然可以通过索引来访问字符串的字符,例如:

void type(const string &letters) 
{ 
    unsigned int wait = 30000000; 

    system("clear"); 
    for(size_t i = 0; i < letters.length(); i++) 
    { 
     usleep(wait) 
     cout << letters[i]; 
    } 
}