【问题标题】:C++ program crashes downC++ 程序崩溃
【发布时间】:2013-11-01 07:41:26
【问题描述】:

我正在使用 C++ 做一个项目,当我尝试运行它时,我的程序不断崩溃……这是我的代码(两个文件:ma​​in.cppPlacementHead. cpp):

main.cpp:

#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <ctime>
#include <climits>
#include "PlacementHead.h"

// Main

int main (int argc, char * const argv[]) {

        PlacementHead h1(4,2,1,"aabcbbca");
        PlacementHead h2(4,2,1,"babcabca");

    return 0;
}

PlacementHead.cpp:

#include "PlacementHead.h"
#include <string>
#include <iostream>
#include <string.h>

PlacementHead::PlacementHead(int width, int height, int gap, char* s) {
    width_ = width;
    height_ = height;
    gap_ = gap;
    size_ = width*height;
    set_ = new char[size_];
    from_ = new int[size_];
    original_ = new char[size_];
    strcpy(set_,s);
    strcpy(original_,s);
}

PlacementHead::~PlacementHead() {

}

int PlacementHead::getSize() { return size_; }
int PlacementHead::getHeight() { return height_; }
int PlacementHead::getWidth() { return width_; }
int PlacementHead::getGap() { return gap_; }

char PlacementHead::getNozzle(int i) {
    return set_[i-1];
}

void PlacementHead::setNozzle(int i, char c) {
    set_[i-1] = c;
}

void PlacementHead::markNozzle(int i, int bankPos) {
    set_[i-1] = ' ';
    from_[i-1] = bankPos;
}

int PlacementHead::getNextUnmarkedPos() {
    for (int i=0; i<size_; i++) {
        if (set_[i]!=' ') {
            return i+1;
        }
    }
    return 0;
}

int PlacementHead::getBankPos(int i) {
    return from_[i-1];
}

void PlacementHead::reset() {
    //for (int i=0; i<size_; i++) {
    //  set_[i] = original_[i];
    //}
    strcpy(set_,original_);
}

void PlacementHead::print() {
    std::cout << "placementhead:\n";
    for (int h=height_; h>0; h--) {
        for (int w=width_; w>0; w--) {
            int i = ((h-1)*width_)+w;
            std::cout << getNozzle(i);
        }
        std::cout << "\n";
    }
}

如果我尝试运行 main.cpp,我会得到:

一旦我也得到了这个(我不是每次都得到这个,这让我很烦恼......):

现在还需要考虑一件事:如果我注释掉创建 PlacementHead h2-object 的第二行代码运行正常,但如果我创建多个 PlacementHead-objects 程序再次崩溃...

任何建议可能导致这种情况? 感谢您的任何帮助!! =)

附言

我的平台是 Windows 7、Codeblocks 12.11 和 GNU GCC 编译器

更新:

如果您在这里看不到第二张图片上的文字:

【问题讨论】:

    标签: c++ debugging gcc crash codeblocks


    【解决方案1】:

    你应该

    • size_ 增加+1 以避免缓冲区溢出(或者,改用std::vector,见下文)
    • 禁用复制构造/分配
    • 添加适当的析构函数
    • 使用初始化列表
    • 检查成员的声明顺序(因为这也是成员初始化的顺序!)
    • 删除默认构造函数,因为它不初始化单个成员
    • 在现代编译器上包含 &lt;cstring&gt; 而不是 &lt;string.h&gt;(这样您就可以获得命名空间 C 标准库函数)

    考虑使用std::vector 而不是手动数组。这将为您省去很多麻烦。想想你将如何让你的构造函数异常安全?

    这是一个修复上述所有问题的示例:

    #include <iostream>
    #include <vector>
    #include <cstring>
    
    struct PlacementHead {
        int width_, height_, gap_;
        size_t size_;
    
        std::vector<char> set_, original_;
        std::vector<int> from_;
    
        PlacementHead(int width, int height, int gap, const char* s) :
            width_(width),
            height_(height),
            gap_(gap),
            size_(width * height),
            set_(s, s + std::min(strlen(s), size_)),
            original_(set_),
            from_(size_)
        {
            set_.resize(size_);
            original_.resize(size_);
    
        }
    
        size_t getSize() { return size_; }
        int getHeight() { return height_; }
        int getWidth() { return width_; }
        int getGap() { return gap_; }
    
        char getNozzle(int i) { return set_[i - 1]; }
    
        void setNozzle(int i, char c) { set_[i - 1] = c; }
    
        void markNozzle(int i, int bankPos) {
            set_[i - 1] = ' ';
            from_[i - 1] = bankPos;
        }
    
        int getNextUnmarkedPos() {
            for(unsigned i = 0; i < size_; i++) {
                if(set_[i] != ' ') {
                    return i + 1;
                }
            }
            return 0;
        }
    
        int getBankPos(int i) { return from_[i - 1]; }
    
        void reset() {
            //for (int i=0; i<size_; i++) {
            //  set_[i] = original_[i];
            //}
            set_ = original_;
        }
    
        void print() {
            std::cout << "placementhead:\n";
            for(int h = height_; h > 0; h--) {
                for(int w = width_; w > 0; w--) {
                    int i = ((h - 1) * width_) + w;
                    std::cout << getNozzle(i);
                }
                std::cout << "\n";
            }
        }
    };
    
    // Main
    
    int main (int argc, char * const argv[]) {
    
        PlacementHead h1(4,2,1,"aabcbbca");
        PlacementHead h2(4,2,1,"babcabca");
    
        return 0;
    }
    

    【讨论】:

    • 我刚刚添加了使用std::vector 而不是手动内存管理的示例。这更安全:该类是可复制的,具有异常安全初始化并且不再泄漏。您仍然应该对所有索引添加边界检查。
    • +1 再次感谢@sehe 感谢大家的帮助!对不起,我只能接受一个答案,我必须赞扬更彻底的工作:) 你所做的一切都很重要!
    【解决方案2】:

    size_ = width*height; 应该是size_ = (width*height)+1;,因此字符串可以以空值结尾。目前您正在写入未分配的内存,导致未定义的行为

    【讨论】:

    • +1 非常感谢您的帮助!!非常感谢:) 这个做到了!谢谢你:)
    【解决方案3】:

    您的构造函数中有一个错误,因为您尝试复制的字符串不是 8 个字符,而是 9 个字符。原因是所有字符串文字也包含额外的特殊字符串终止字符。

    如果您在 C++ 中使用字符串,请使用 std::string,它将极大地帮助您解决此类问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-02
      • 2012-04-16
      相关资源
      最近更新 更多