Collat​​z和其他序列:如何轻松获得更高的精度并避免段错误?

时间:2015-06-13 11:14:21

标签: java c performance

这是一个简单的C程序,我是从一些旧的Java代码创建的(我的第一个C程序,所以很好;))。这比相应的Java代码运行得快得多,但Java允许我在崩溃之前更加精确(我也在Java中使用long)。

令我惊讶的是,Java代码在输入超过170,000,000之前不会崩溃。 C代码无法处理超过1,050,000的任何内容。有关使这个C代码运行得更好而不需要一些疯狂的库的任何建议?谢谢!

#include <stdio.h>
#include <string.h> /* lets me use memset */
#include <stdlib.h> /* home of strtoull */

/* segfault 11 after 1047993 (Not anymore!!) */ 

unsigned long long getnext( unsigned long long x );

unsigned long long getnext( unsigned long long x )
{
    if (x == 1) { return 1; }
    if (x % 2 == 0) { return x/2; }
    return (3 * x + 1);
}

int main(int argc, char *argv[])
{
    int argind;
    for ( argind = 0; argind < argc; argind++ )
    {
        unsigned long long intrange;
        intrange = strtoull(argv[argind], NULL, 10);

       /** Improper allocation of memory. Fixed directly below. Thanks Marcus!
        * unsigned long long lengths[intrange+1];
        * memset(lengths, 0, sizeof(lengths));
        */ 

        unsigned long long *lengths= malloc((intrange+1) * sizeof(unsigned long long)); /* ptr points to mem. location of lengths array. */
        memset(lengths, 0, (intrange+1) * sizeof(unsigned long long));

        unsigned long long longestlen[2];
        unsigned long long seqindex;
        unsigned long long origdex;

        longestlen[0] = 0;
        longestlen[1] = 0;

        for (origdex = 2; origdex <= intrange; origdex++) 
        {
            seqindex = origdex;
            while ( seqindex > 1 )
            {
                lengths[ origdex ] += 1;
                seqindex = getnext(seqindex);

                if ( seqindex <= intrange )
                {
                    if ( lengths[ seqindex ] > 0)
                    {
                        lengths[ origdex ] =  lengths[ origdex ] + lengths[ seqindex ];
                        if ( lengths[origdex] > longestlen[1] ) { longestlen[0] = origdex; longestlen[1] = lengths[origdex]; }
                        seqindex = 1;
                        continue;
                    }
                }
            }
        }
        if(longestlen[0] > 0 ){ printf("Longest Collatz sequence for first %llu positive integers found at %llu with length %llu. \n", intrange, longestlen[0], longestlen[1]); }

    }
    return 0 ;
}

1 个答案:

答案 0 :(得分:3)

如果让程序运行调试器(在我的情况下:

gcc -o collatz -g collatz.c
gdb --args collatz 2000000
$run
...segfault at memset(lengths,0,sizeof(lengths))...

), 当你试图访问长度时,你会发现你的段错误发生了!

关键是你为数组做错误的动态内存分配;这在C中有点棘手(这就是为什么我通常建议来自其他语言的人学习现代C ++而不是C)。

你应该做

unsigned long long *lengths = malloc(...);

给你新分配的记忆。

此外,sizeof(lengths)然后是错误的,因为那将是指向数组开头地址的指针的大小。请改用sizeof(unsigned long long)。当然,您的代码必须阅读memset(lengths, 0, sizeof(unsigned long long)*(intrange+1))以将intrange+1占用的unsigned long long字节数0倍设置为malloc字节。

有关man malloc的详细信息,如果您使用man的系统,则可以使用malloc;通常,你必须&#34;发布&#34;使用后使用free(ptr)分配的内存。在您的情况下,一旦程序终止,它就会自动完成,但是对于更复杂的软件,在您不再需要type *ptr = malloc(...)后,std::vector不会调用ActiveRecord::AssociationTypeMismatch in LinksController#create Level(#70251425229100) expected, got String(#70251404789620) Extracted source (around line #27): # POST /links.json def create @link = current_user.links.build(link_params) respond_to do |format| if @link.save Rails.root: /Users/victorblomberg/startcode_co内存是内存泄漏。

同样,这是一个非常典型的C问题。如果你用C ++编写代码,那么你几乎不会有任何性能损失,能够使用像activerecord (4.2.1) lib/active_record/associations/association.rb:216:in `raise_on_type_mismatch!' activerecord (4.2.1) lib/active_record/associations/belongs_to_association.rb:12:in `replace' activerecord (4.2.1) lib/active_record/associations/singular_association.rb:17:in `writer' activerecord (4.2.1) lib/active_record/associations/builder/association.rb:123:in `level=' activerecord (4.2.1) lib/active_record/attribute_assignment.rb:54:in `public_send' activerecord (4.2.1) lib/active_record/attribute_assignment.rb:54:in `_assign_attribute' activerecord (4.2.1) lib/active_record/attribute_assignment.rb:41:in `block in assign_attributes' actionpack (4.2.1) lib/action_controller/metal/strong_parameters.rb:183:in `each_pair' actionpack (4.2.1) lib/action_controller/metal/strong_parameters.rb:183:in `each_pair' activerecord (4.2.1) lib/active_record/attribute_assignment.rb:35:in `assign_attributes' activerecord (4.2.1) lib/active_record/core.rb:559:in `init_attributes' activerecord (4.2.1) lib/active_record/core.rb:281:in `initialize' activerecord (4.2.1) lib/active_record/inheritance.rb:61:in `new' activerecord (4.2.1) lib/active_record/inheritance.rb:61:in `new' activerecord (4.2.1) lib/active_record/reflection.rb:131:in `build_association' activerecord (4.2.1) lib/active_record/associations/association.rb:247:in `build_record' activerecord (4.2.1) lib/active_record/associations/collection_association.rb:146:in `build' activerecord (4.2.1) lib/active_record/associations/collection_proxy.rb:259:in `build' app/controllers/links_controller.rb:27:in `create' actionpack (4.2.1) lib/action_controller/metal/implicit_render.rb:4:in `send_action' actionpack (4.2.1) lib/abstract_controller/base.rb:198:in `process_action' actionpack (4.2.1) lib/action_controller/metal/rendering.rb:10:in `process_action' actionpack (4.2.1) lib/abstract_controller/callbacks.rb:20:in `block in process_action' activesupport (4.2.1) lib/active_support/callbacks.rb:117:in `call' activesupport (4.2.1) lib/active_support/callbacks.rb:117:in `call' activesupport (4.2.1) lib/active_support/callbacks.rb:555:in `block (2 levels) in compile' activesupport (4.2.1) lib/active_support/callbacks.rb:505:in `call' activesupport (4.2.1) lib/active_support/callbacks.rb:505:in `call' activesupport (4.2.1) lib/active_support/callbacks.rb:92:in `_run_callbacks' activesupport (4.2.1) lib/active_support/callbacks.rb:776:in `_run_process_action_callbacks' activesupport (4.2.1) lib/active_support/callbacks.rb:81:in `run_callbacks' actionpack (4.2.1) lib/abstract_controller/callbacks.rb:19:in `process_action' actionpack (4.2.1) lib/action_controller/metal/rescue.rb:29:in `process_action' actionpack (4.2.1) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action' activesupport (4.2.1) lib/active_support/notifications.rb:164:in `block in instrument' activesupport (4.2.1) lib/active_support/notifications/instrumenter.rb:20:in `instrument' activesupport (4.2.1) lib/active_support/notifications.rb:164:in `instrument' actionpack (4.2.1) lib/action_controller/metal/instrumentation.rb:30:in `process_action' actionpack (4.2.1) lib/action_controller/metal/params_wrapper.rb:250:in `process_action' activerecord (4.2.1) lib/active_record/railties/controller_runtime.rb:18:in `process_action' actionpack (4.2.1) lib/abstract_controller/base.rb:137:in `process' actionview (4.2.1) lib/action_view/rendering.rb:30:in `process' actionpack (4.2.1) lib/action_controller/metal.rb:196:in `dispatch' actionpack (4.2.1) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch' actionpack (4.2.1) lib/action_controller/metal.rb:237:in `block in action' actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:74:in `call' actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:74:in `dispatch' actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:43:in `serve' actionpack (4.2.1) lib/action_dispatch/journey/router.rb:43:in `block in serve' actionpack (4.2.1) lib/action_dispatch/journey/router.rb:30:in `each' actionpack (4.2.1) lib/action_dispatch/journey/router.rb:30:in `serve' actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:819:in `call' warden (1.2.3) lib/warden/manager.rb:35:in `block in call' warden (1.2.3) lib/warden/manager.rb:34:in `catch' warden (1.2.3) lib/warden/manager.rb:34:in `call' rack (1.6.1) lib/rack/etag.rb:24:in `call' rack (1.6.1) lib/rack/conditionalget.rb:38:in `call' rack (1.6.1) lib/rack/head.rb:13:in `call' actionpack (4.2.1) lib/action_dispatch/middleware/params_parser.rb:27:in `call' actionpack (4.2.1) lib/action_dispatch/middleware/flash.rb:260:in `call' rack (1.6.1) lib/rack/session/abstract/id.rb:225:in `context' rack (1.6.1) lib/rack/session/abstract/id.rb:220:in `call' actionpack (4.2.1) lib/action_dispatch/middleware/cookies.rb:560:in `call' activerecord (4.2.1) lib/active_record/query_cache.rb:36:in `call' activerecord (4.2.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:649:in `call' activerecord (4.2.1) lib/active_record/migration.rb:378:in `call' actionpack (4.2.1) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call' activesupport (4.2.1) lib/active_support/callbacks.rb:88:in `call' activesupport (4.2.1) lib/active_support/callbacks.rb:88:in `_run_callbacks' activesupport (4.2.1) lib/active_support/callbacks.rb:776:in `_run_call_callbacks' activesupport (4.2.1) lib/active_support/callbacks.rb:81:in `run_callbacks' actionpack (4.2.1) lib/action_dispatch/middleware/callbacks.rb:27:in `call' actionpack (4.2.1) lib/action_dispatch/middleware/reloader.rb:73:in `call' actionpack (4.2.1) lib/action_dispatch/middleware/remote_ip.rb:78:in `call' actionpack (4.2.1) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call' web-console (2.1.2) lib/web_console/middleware.rb:37:in `call' actionpack (4.2.1) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call' railties (4.2.1) lib/rails/rack/logger.rb:38:in `call_app' railties (4.2.1) lib/rails/rack/logger.rb:20:in `block in call' activesupport (4.2.1) lib/active_support/tagged_logging.rb:68:in `block in tagged' activesupport (4.2.1) lib/active_support/tagged_logging.rb:26:in `tagged' activesupport (4.2.1) lib/active_support/tagged_logging.rb:68:in `tagged' railties (4.2.1) lib/rails/rack/logger.rb:20:in `call' actionpack (4.2.1) lib/action_dispatch/middleware/request_id.rb:21:in `call' rack (1.6.1) lib/rack/methodoverride.rb:22:in `call' rack (1.6.1) lib/rack/runtime.rb:18:in `call' activesupport (4.2.1) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call' rack (1.6.1) lib/rack/lock.rb:17:in `call' actionpack (4.2.1) lib/action_dispatch/middleware/static.rb:113:in `call' rack (1.6.1) lib/rack/sendfile.rb:113:in `call' railties (4.2.1) lib/rails/engine.rb:518:in `call' railties (4.2.1) lib/rails/application.rb:164:in `call' rack (1.6.1) lib/rack/lock.rb:17:in `call' rack (1.6.1) lib/rack/content_length.rb:15:in `call' rack (1.6.1) lib/rack/handler/webrick.rb:89:in `service' /Users/victorblomberg/.rbenv/versions/2.2.2/lib/ruby/2.2.0/webrick/httpserver.rb:138:in `service' /Users/victorblomberg/.rbenv/versions/2.2.2/lib/ruby/2.2.0/webrick/httpserver.rb:94:in `run' /Users/victorblomberg/.rbenv/versions/2.2.2/lib/ruby/2.2.0/webrick/server.rb:294:in `block in start_thread'这样的东西为你提供具有自动构造和值填充的​​可变大小的数组,这将自动被释放在离开声明范围时。