以下是相关代码:
long number = atol(argv[1]);
long prime_limit = number / 2;
int * primes = malloc(sizeof(int) * prime_limit);
long i;
for (i = 2; i <= prime_limit; i++) {
primes[i] = 1; # This is line 16
}
以下是错误:
==9318== Invalid write of size 4
==9318== at 0x40065B: main (003.c:16)
==9318== Address 0x8 is not stack'd, malloc'd or (recently) free'd
==9318==
==9318==
==9318== Process terminating with default action of signal 11 (SIGSEGV)
==9318== Access not within mapped region at address 0x8
==9318== at 0x40065B: main (003.c:16)
==9318== If you believe this happened as a result of a stack
==9318== overflow in your program's main thread (unlikely but
==9318== possible), you can try to increase the size of the
==9318== main thread stack using the --main-stacksize= flag.
==9318== The main thread stack size used in this run was 8388608.
我认为错误必须是我使用malloc的方式,但我不太确定。 argv [1]的值是600851475143。
答案 0 :(得分:5)
数组是0
- 来自C:
i <= prime_limit;
应该是
i < prime_limit;
否则atol
不安全,无法进行错误检测。使用strtol
将字符串转换为long
。
答案 1 :(得分:2)
您的分配失败:
=9318== Address 0x8 is not stack'd, malloc'd or (recently) free'd
...因为您尝试分配600851475143 * 4/2或1201702950288字节或1.2TB,哪种有意义。
因此,{p>primes
NULL
并且您在执行primes[i]
时尝试取消引用它,从而导致未定义的行为。
为了进行比较,如果你写的是经过适当分配的内存块的边界,Valgrind将提供类似于的输出:
==10088== Address 0x51f104c is 0 bytes after a block of size 12 alloc'd
始终检查malloc
的返回值:
int * primes = malloc(sizeof(int) * prime_limit);
if (primes == NULL) {
perror("Allocation failure!");
/* handle error */
}
不要试图一次性分配1TB ......
答案 2 :(得分:0)
除了发布的内容之外,我认为你应该检查malloc()返回的指针值。您可能无法分配所请求的内存量。