如何运行无限循环?

时间:2015-09-20 03:38:29

标签: c++ loops

我想基本上永远地一遍又一遍地运行一些代码,但我不希望我的计算机耗尽内存或类似的东西。所以我想知道我怎么能用c ++做到这一点?我做到了。

for (int i = 0; i <= 2; i++) {
    if (i == 1) {i = 0;}
    //My code here
}

我想知道这会对我的电脑造成什么坏处吗?

4 个答案:

答案 0 :(得分:8)

while(true)
{
    //Your code here
}

答案 1 :(得分:5)

如果您更喜欢for语法:

for ( ; ; ) {
    // do stuff.
}

如果您在没有释放内存的情况下分配内存,则无限循环不会导致计算机内存不足。

答案 2 :(得分:2)

有一些编写无限循环的常用方法。

for (;;) {
   // do something over an over again
}

while (true) {
   // do something over an over again
}

本身,无限循环不会导致程序内存不足。但是如果你分配内存并忘记释放它,那么 会导致内存泄漏。鉴于此,以下代码可以正常使用:

YourClass* p;
for (;;) {
    p = new YourClass();    // every time the loop runs, a new instance of the class is created
    // [do something useful with the object]
    delete p;   // clean-up: deallocate the object.
}

但这会导致内存泄漏:

YourClass* p;
for (;;) {
    p = new YourClass();    // every time the loop runs, a new instance of the class is created
    // [do something useful with the object]
    // oups... forgot to deallocate the object.
}

答案 3 :(得分:1)

如果您知道如何管理它们,那么无限循环就很棒。即使使用无限循环,您仍然需要可能的退出条件。如果您正在设计无限循环,根据其数据集,在循环中没有可能的退出,最安全的做法是跟踪应用程序对象的实例及其当前状态,以及何时状态更改为退出然后,任何线程上运行的任何无限循环都可以针对此进行测试,并在可用时自动退出,以防止计算机挂起到需要进行硬重置或关闭的位置。只需确保在触发此事件时清除所有内存。现在,如果您有多个并行或异步运行的线程,并且它们由队列或事件触发器列表管理,那么每个循环都可能需要一段时间才能退出,具体取决于您指定在CRITICAL_SECTION中的循环。

class Application {
public:
    enum ApplicationState {
        APPLICATION_RUNNING = 0,
        APPLICATION_PAUSED,  // Out of Focus or Paused If In A Timed Situation
        APPLICATION_EXIT,
    };
private:
    // Member Variables Such As Window Handle, Time Etc.,
    ApplicationState m_state;
public:
    Application();
    // virtual ~Application(); // Default Okay - Use Virtual If Using Inheritance
    ApplicationState getState() const { return m_state; }

    bool start() { m_sate = APPLICATION_RUNNING; return true; }
    bool pause() { m_state = APPLICATION_PAUSED; return true; } 
    // resume may keep track of time if the application uses a timer.
    // This is what makes it different than start() where the timer
    // in start() would be initialized to 0. And the last time before
    // paused was trigger would be saved, and then reset as new starting
    // time for your timer or counter. 
    bool resume() { m_state = APPLICATION_RUNNING; return true; }      
    bool exit(); { m_state = APPLICATION_EXIT;  return false; }

};

int main() {
    Application app;
    app.start();

    // One Type Of Infinite Loop, with a safety net.
    while ( !app.exit() ) {
        // do some work
    }

    // Another Type Similar But Different
    while ( app.getState() == Application::APPLICATION_RUNNING ) {
      // do some work  
    } 

    // A Third Type
    while ( true ) {
       switch( app.getState() ) {
           case Application::APPLICATION_RUNNING {
               app.start(); // If Not Done Above Outside of Loop
               // Do Some Work
               break;
           }
           case Application::APPLICATION_PAUSE {
               // Wait Till You Has Focus Or Continues
               break;
           }
           case Application::APPLICATION_EXIT {
               // Change The Application State
               app.pause();
               break;
           }
           default: {
               // ErrorHandling Throw An Exception Etc.
           }

        } // switch
    } while

    return 0;
}

您可能不一定在main.cpp中看到的一些类型的方法。 您会在应用程序类中看到这些类型的循环,这些循环是私有的并且是公开调用的,这样您的main.cpp就会看起来更干净:

的main.cpp

#include "Application.h"

int main() {

    try {
        // Initialize Loggers, Settings, Process - Thread Blockers etc.

        // Handle Input Arguements

        // Give The Main Thread Application, Window Handle, Mutex etc, A Unique Name
        const std::string strApplicationName( "My Application" );
        Application app( strApplicationName );
        app.start();

        }

    } catch( YourTypes& e ) {
        // Print Errors To Either File Or Console
        return RETURN_ERROR; 
    } catch ( ... ) {  // Default Types
        // Print Errors To Either File Or Console 
        return RETURN_ERROR;     
    } 

    return RETURN_OK; // return 0;
}

这样你的主要是干净的,易于遵循,你的循环发生在你的应用程序类对象中。这样,只要应用程序正在运行,您仍然可以运行无限循环。现在,如果您正在编写驱动程序,文件或内存监视器,恶意软件或防病毒dll或在Windows后台运行的进程,那么您可能不希望出现这种情况,但由于这些进程在Windows的后台运行,因此如果这样做仍然是安全的。进程或可执行文件超出范围并结束我们仍然希望安全地退出所有循环并清理所有内存!

这里的范例是安全有效地管理结构良好的应用程序。我以此为例的原因在于,当您远离编写事件驱动或数据驱动类型的应用程序并且正在使用任何类型的游戏开发时,这是一个合适的模型。唯一的区别,而不是将您的类命名为Application,您很可能将其命名为Game并让Game继承Engine类。这样,代码可重复用于构建和开发多个游戏。它足够通用,可以处理所有图形,声音,字体,渲染等,而这个Engine类将是抽象的,这个基类不能自己实例化,你必须创建一个Game类对象作为一个继承的类,可以实例化。您可能还希望Engine类继承自Singleton类,以便您只能拥有Game:Engine对象的一个​​实例。然后,Game类将负责所有正在加载的资产,正在加载的关卡设计,哪些字体和字体。声音要加载,要加载的动画等等,这个游戏独有的东西。这使它非常模块化。此设置还需要Engine构建多个严重依赖模板的Manager类型类。

以下不是我的工作,而是一个我一直在努力的项目,所有功劳都归功于Marek A. Krzeminski,MASc http://www.marekknows.com此摘录显示了main.cpp文件。

// Version: 1.0
// Copyright (c) 2012 by Marek A. Krzeminski, MASc
// Marek@MarekKnows.com

#include "stdafx.h"
#include "BuildConfig.h"
#include "Settings.h"
#include "BlockProcess.h"
#include "Logger.h"
#include "Utility.h"

#include "Game.h"

// ----------------------------------------------------------------------------
// _tmain()
// Main Entry Point Into Application
int _tmain( int iNumArguments, _TCHAR* pArgumentText[] ) {
    using namespace vmk;

    try {
        // Test If Engine Is Supported By This Compiler
        Utility::testPlatform();

        Logger logger( "logger.txt" );
        Settings settings;

        // Prevent Starting Game Multiple Times At Once
        BlockProcess processBlocker( settings.getNameAndVersion() );
        if ( processBlocker.isBlocked() ) {
            std::ostringstream strStream;
            strStream << settings.getNameAndVersion() << " is already running in another window" << std::endl;
            throw ExceptionHandler( strStream, false );
        }

        // Handle Input Arguments
        bool bShowHelp = false;
        for ( int i = 1; i < iNumArguments; ++i ) {
            std::ostringstream strStream;
            strStream << "Input Argument " << i << ": " << pArgumentText[i];

            std::string strArgument( Utility::toLower( std::string( pArgumentText[i] ) ) );

            if ( strArgument.compare( "/?" ) == 0 || strArgument.compare( "help" ) == 0 ) {
                bShowHelp = true;
            } else if ( strArgument.compare( "window" ) == 0 ) {
                settings.setWindowDisplayMode( true );
            } else if ( strArgument.compare( "debug_memory" ) == 0 ) {
                settings.setDebugLogging( settings.getDebugLogging() | Settings::DEBUG_MEMORY );
            } else if ( strArgument.compare( "seed" ) == 0 ) {
                // Need Next Argument To Know Which Seed Value To Use
                bool bError     = false;
                unsigned uSeedValue = 0;
                if ( i + 1 < iNumArguments ) {
                    uSeedValue = Utility::convertToUnsigned( std::string( pArgumentText[i+1] ) );
                    if ( uSeedValue == 0 ) {
                        bError = true;
                    } else {
                        settings.setRandomNumberSeed( uSeedValue );
                        i++; // Move Argument Counter Past Seed Value
                    }
                } else {
                    bError = true;
                }

                if ( bError ) {
                    // Missing Argument For Seed Value
                    std::cout << " <- Missing Seed Value After This Argument";
                } else {
                    // Display Seed Value To Use
                    strStream << " " << uSeedValue;
                }           
            } else {
                strStream << " <- Unrecognized input argument";
            }

            Logger::log( strStream, Logger::TYPE_CONSOLE );
        }

        if ( bShowHelp ) {
            std::ostringstream strStream;
            strStream << std::endl
                      << settings.getNameAndVersion() << " command line arguments:" << std::endl
                      << "  seed nnn     | Supply seed value (nnn) to use in random number generator" << std::endl
                      << "  window       | Run the program in a window rather then full screen" << std::endl
                      << "  debug_memory | Log extra messages when objects are allocated in memory" << std::endl
                      << std::endl;
            Logger::log( strStream, Logger::TYPE_CONSOLE );

        } else {
            // Run The Game Here
            Game game;
            game.start();

        } 
    } catch( ExceptionHandler& e ) {
        std::cout << "Exception Thrown: " << e.getMessage() << std::endl;
        Utility::pressAnyKeyToQuit();
        return RETURN_ERROR;
    } catch( ... ) {
        std::cout << __FUNCTION__ << " Caught Unknown Exception" << std::endl;
        Utility::pressAnyKeyToQuit();
        return RETURN_ERROR;
    }

    return RETURN_OK;

 } // _tmain

正如你所看到的那样,没有可见的无限while或for循环可见,因为这种类型的算法嵌套在Game-Engine对象的深处。