因此,我试图编写一个代码,该代码可以找到10000000000000000之前的所有素数。因此,在某些变量中使用uint64_t。我也想将结果放在纯文本文件中,听起来很简单。或那是我的想法。我用编译代码

gcc -lm --std=c11 primenumbers.c -o primes


我得到0错误或警告...对我有好处!但是当我执行程序时,我收到了可怕的错误消息


分段故障(核心已转储)


起初我以为可能是我没有为字符串正确分配内存,所以当我需要增大字符串时,我继续在各处使用malloc() / free(0,不,它仍然不断显示。

所以这是代码:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>
#include <inttypes.h>
#include <stdlib.h>

bool test_number(uint64_t c);

int main(void){
    uint64_t b = 10000000000000;
    uint64_t i;
    char *s = " ";
    char *helper = "";
    char *helper_two;
    char *helper_three;
    int format = 0;

    FILE *ptrPrimes;


    for(i = 2; i <= b; i++){
        if (test_number(i)){
            format++;
            sprintf(helper_three, "%llu", i);
            helper = malloc(strlen(s));
            helper_two = malloc(sizeof(strlen(helper_three)) + 1);
            sprintf(helper_two, " %s", helper_three);
            strcpy(helper, s);
            free(s);
            if(format % 120 == 0){
                s = malloc(sizeof(helper) + sizeof(helper_two) + 1);
                sprintf(s, "%s%s\n", helper, helper_two);
            }else{
                s = malloc(sizeof(helper) + sizeof(helper_two));
                sprintf(s, "%s%s", helper, helper_two);
            }
            free(helper);
            free(helper_two);
            helper_three = NULL;
        }
    }

    if((ptrPrimes = fopen("primenumbers.txt", "w")) != NULL){
        fprintf(ptrPrimes, "%s", s);
    }else{
        printf("Sorry mate, an error curred\n");
    }

    return 0;
}

bool test_number(uint64_t c){
    uint64_t i;
    c = sqrt(c);
    for(i = 2; i <= c; i++){
        if(c % i == 0) return false;
    }
    return true;
}


然后我认为这可能是在for标头中使用uint64_t的原因。那么您认为这可能是错误吗?

编辑

我尝试了所有建议以及其他一些建议,现在的代码如下所示:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdbool.h>

bool test_number(uint64_t c);

int main(void){
    uint64_t b = 10000000000000;
    uint64_t i;
    char *s;
    char *helper;
    char *helper_two;
    char *helper_three;
    uint64_t format = 0;

    FILE *ptrPrimes;


    for(i = 2; i <= b; i++){
        if (test_number(i)){
            printf("%llu\n", i);
            format++;
            helper_three = malloc(sizeof(char) * snprintf(NULL, 0, "%llu", i));
            sprintf(helper_three, "%llu", i);
            helper = malloc(sizeof(char) * strlen(s));
            helper_two = malloc(sizeof(char) * strlen(helper_three) + 1);
            sprintf(helper_two, " %s", helper_three);
            strcpy(helper, s);
            if(format % 120 == 0){
                s = malloc(sizeof(char) * strlen(helper) + sizeof(char) * strlen(helper_two) + 1);
                sprintf(s, "%s%s\n", helper, helper_two);
            }else{
                s = malloc(sizeof(char) * strlen(helper) + sizeof(char) * strlen(helper_two));
                sprintf(s, "%s%s", helper, helper_two);
            }
            free(helper);
            free(helper_two);
            free(helper_three);
        }
    }

    if((ptrPrimes = fopen("primenumbers.txt", "w")) != NULL){
        fprintf(ptrPrimes, "%s", s);
    }else{
        printf("Sorry mate, an error curred\n");
    }

    return 0;
}

bool test_number(uint64_t c){
    uint64_t i;
    uint64_t b = sqrt(c);
    for(i = 2; i <= b; i++){
        if(!(i % 2) && i != 2) continue;
        if(c % i == 0) return false;
    }
    return true;
}


而且在数字29之后一切正常,由于某种原因(显然),我收到了此错误消息:


2
3
5
7
11
13
17
19
23
29

*`./primes'中的错误:free():下一个大小无效(快速):0x000000000258f100 *

=======回溯:========= /lib64/libc.so.6(+0x77e35)[0x7f8f212abe35]
/lib64/libc.so.6(+0x8051a)[0x7f8f212b451a]
/lib64/libc.so.6(cfree+0x4c)[0x7f8f212b7ccc]
./primes[0x400a8f]
/lib64/libc.so.6(__libc_start_main+0xf0)[0x7f8f21254580]
./primes[0x4007b9]
=======内存映射:======== 00400000-00401000 r-xp 00000000 fd:02 13507592 / home / lain / primes 00601000-00602000
r--p 00001000 fd:02 13507592
/ home / lain / primes 00602000-00603000 rw-p 00002000 fd:02 13507592
/ home / lain / primes 0258f000-025b0000 rw-p 00000000 00:00 0
[堆] 7f8f1c000000-7f8f1c021000 rw-p 00000000 00:00 0
7f8f1c021000-7f8f20000000 --- p 00000000 00:00 0
7f8f2101d000-7f8f21033000 r-xp 00000000 fd:00 789942
/usr/lib64/libgcc_s-5.3.1-201 7f8f21033000-7f8f21232000 --- p 00016000
fd:00 789942 /usr/lib64/libgcc_s-5.3.1-201
7f8f21232000-7f8f21233000 r--p 00015000 fd:00 789942
/usr/lib64/libgcc_s-5.3.1-201 7f8f21233000-7f8f21234000 rw-p 00016000
fd:00 789942 /usr/lib64/libgcc_s-5.3.1-201
7f8f21234000-7f8f213eb000 r-xp 00000000 fd:00 788930
/usr/lib64/libc-2.22.so 7f8f213eb000-7f8f215eb000 --- p 001b7000 fd:00
788930 /usr/lib64/libc-2.22.so
7f8f215eb000-7f8f215ef000 r--p 001b7000 fd:00 788930
/usr/lib64/libc-2.22.so 7f8f215ef000-7f8f215f1000 rw-p 001bb000 fd:00
788930 /usr/lib64/libc-2.22.so
7f8f215f1000-7f8f215f5000 rw-p 00000000 00:00 0
7f8f215f5000-7f8f216f6000 r-xp 00000000 fd:00 788938
/usr/lib64/libm-2.22.so 7f8f216f6000-7f8f218f5000 --- p 00101000 fd:00
788938 /usr/lib64/libm-2.22.so
7f8f218f5000-7f8f218f6000 r--p 00100000 fd:00 788938
/usr/lib64/libm-2.22.so 7f8f218f6000-7f8f218f7000 rw-p 00101000 fd:00
788938 /usr/lib64/libm-2.22.so
7f8f218f7000-7f8f21918000 r-xp 00000000 fd:00 788921
/usr/lib64/ld-2.22.so 7f8f21ad3000-7f8f21ad6000 rw-p 00000000 00:00 0
7f8f21b14000-7f8f21b17000 rw-p 00000000 00:00 0
7f8f21b17000-7f8f21b18000 r--p 00020000 fd:00 788921
/usr/lib64/ld-2.22.so 7f8f21b18000-7f8f21b19000 rw-p 00021000 fd:00
788921 /usr/lib64/ld-2.22.so
7f8f21b19000-7f8f21b1a000 rw-p 00000000 00:00 0
7fffa035b000-7fffa037d000 rw-p 00000000 00:00 0
[堆栈] 7fffa0381000-7fffa0383000 r--p 00000000 00:00 0
[vvar] 7fffa0383000-7fffa0385000 r-xp 00000000 00:00 0
[vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0
[vsyscall]


而且我不太明白为什么一切都正常,直到“ 29”。

最佳答案

在您的代码中

  sprintf(helper_three, "%llu", i);


helper_three未分配任何内存。因此,helper_three指向的内存位置本质上无效。任何访问无效内存的尝试都会调用undefined behavior。分割错误是副作用之一。

您需要先将内存分配给helper_three,然后再写入。

之后,

 helper_two = malloc(sizeof(strlen(helper_three)) + 1);


是非常错误的。您需要的是

helper_two = malloc(strlen(helper_three) + 1);


然后,sizeof(helper)和其他sizeof(pointer)不能按您预期的方式工作。在指针上使用sizeof会得出指针本身的大小,而不是分配给指针的内存量。如果这些指针包含一个字符串,则需要使用strlen()来获取大小。

09-12 10:19