[英]Can I use the uint64_t in a for block?
因此,我试图编写一个代码,该代码可以找到uint64_t
之前的所有素数。因此,在某些变量中,我使用uint64_t
。 我也想将结果放在纯文本文件中,听起来很简单。 或那是我的想法。 我用编译代码
gcc -lm --std=c11 primenumbers.c -o primes
我收到0错误或警告...对我有好处! 但是当我执行程序时,我收到了可怕的错误消息
分段故障(核心已转储)
起初我以为可能是我没有为字符串正确分配内存,所以当我需要增大字符串时,我继续在各处使用malloc()
/ free(0
malloc()
,不,它仍然会不断显示。
所以这是代码:
#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
五
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 fd-pf 000 :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-7fffa03700000 000 rw-p 000000 :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
分配任何内存。 因此, helper_three
指向的内存位置helper_three
上不是有效的 。 任何访问无效内存的尝试都将引起未定义的行为 。 分割错误是副作用之一。
写入之前,您需要为helper_three
分配内存。
之后,
helper_two = malloc(sizeof(strlen(helper_three)) + 1);
是非常错误的。 您需要的是
helper_two = malloc(strlen(helper_three) + 1);
然后, sizeof(helper)
和其他sizeof(pointer)
无法按您期望的方式工作。 在指针上使用sizeof
评估指针本身的大小,而不是分配给指针的内存量。 如果这些指针持有一个string ,则需要使用strlen()
来获取大小。
这非常令人不安
sizeof(strlen(...));
您不需要那里的sizeof
。
但是几乎所有的malloc()
以错误的方式分配空间。 如果要预测sprintf()
的长度,请尝试使用长度为NULL
目标缓冲区为0
snprintf()
,检查返回值。
好的,我得到了以下答案:
#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 = 9223372036854775783;
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) == true){
//printf("%llu", i);
format++;
helper_three = malloc(sizeof(char) * snprintf(NULL, 0, "%llu", i));
sprintf(helper_three, "%llu ", i);
helper_two = malloc(sizeof(char) * (strlen(helper_three) + 1));
strcpy(helper_two, helper_three);
if (format == 1){
s = malloc(sizeof(char));
sprintf(s, "%s", helper_three);
}else{
if (s != NULL){
helper = malloc(sizeof(char) * (strlen(s) +1));
strcpy(helper, s);
free(s);
if(format % 120 == 0){
s = malloc(sizeof(char) * strlen(helper) + sizeof(char) * (strlen(helper_two) + 1) +1);
strcpy(s, helper);
strcat(s, helper_two);
strcat(s, "\n");
}else{
s = malloc(sizeof(char) * strlen(helper) + sizeof(char) * (strlen(helper_two) + 1));
strcpy(s, helper);
strcat(s, 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 ocurred\n");
}
return 0;
}
bool test_number(uint64_t c){
uint64_t i;
uint64_t b = sqrt(c);
switch(c){
case 1:
return false;
case 2:
return true;
}
if(c % 2 == 0) return false;
for(i = 3; i <= b; i += 2){
if(c % i == 0) return false;
}
return true;
}
我只是在尝试重新学习C(11)的某些概念,因此没有必要对代码进行优化,这并不是故意的(即使我调整了test_number函数)。 但是无论如何,谢谢大家的帮助。
我一直需要使用sizeof
和strlen
, sizeof
来获取系统上char的大小,并使用strlen
来获取字符串的长度(显然),这样我才能获得适当的内存量来保存字符串。 我不仅应该单独使用strlen
。 我会为一个未知的结构获取内存(以字符串长度的大小为准,这完全没有意义)。
我最大的错误之一是我没有考虑字符串中的'\\ 0'字符。 看起来strlen
忽略了它( 畏缩 )。 再次:感谢您的帮助。
PS:如果您使用clang
,则会由于“%llu”格式说明符而收到警告。 我发现它很有趣,尽管clang
对某些功能的支持会比gcc
。 不想在编译器之间发动战争,两者都是很棒的工具,仅此而已 : tools 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.