簡體   English   中英

堆棧粉碎/回溯

[英]Stack Smashing/BackTrace

我寫了一些代碼,應該采用一個char數組,並使它看起來像計算機在鍵入文本。 很簡單,對不對? 但是當我運行它時,Terminal告訴我:

*** 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];
    }

}

C ++中的字符串應以null終止,即它們的最后一個字符是\\0 在您的代碼中,循環不會在字符串letters的末尾終止,因為您正在尋找\\n字符,該字符實際上不存在於該字符串中。

第一次修復

在循環中使用要查找的字符終止字符串:

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

二次修復

通過查找實際上確實存在的字符串結尾字符\\0來終止循環:

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

第三修正

使用適當的字符串長度檢查作為循環終止條件:

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

或這三者的任意組合。

通常,將字符串聲明為固定大小的數組永遠不是一個好主意,因此請使用const char *letters = "..."; 代替。

您陷入無限循環

您正在尋找不存在的'\\n' 您應該尋找空字符\\0

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

您可以在此處使用兩種解決方案之一。

1)您可以在循環中包含\\ n,但這必須在數組本身中,並且數組大小必須增加1到字母[28]。

2)您保留聲明的數組,但是for循環將是

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

第二種解決方案,您不必更改數組大小,循環將一直持續到數組結尾

除了其他評論者指出的字符串結尾問題外,您的代碼可能也不會如您所願,因為您正在使用cout。 該輸出流將緩沖所有內容,直到您仍然發送換行符為止,這樣,在打印最終換行符時,您的“類型”將立即全部顯示。

通過打印到cerr或在應該打印每個字符后沖洗cout,可以一次獲得一個字符的效果。

如果使用的是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];
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM