1

这是有问题的代码:

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。

4

3 回答 3

4

数组是0C 中的 -origin:

i <= prime_limit;

应该

i < prime_limit;

否则atol不安全,无法进行错误检测。用于strtol将字符串转换为long.

于 2013-02-27T23:09:39.153 回答
2

您的分配失败:

=9318==  Address 0x8 is not stack'd, malloc'd or (recently) free'd

...哪种有意义,因为您正在尝试分配 600851475143 * 4 / 2,或 1201702950288 字节或 1.2TB。

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...

于 2013-02-28T00:18:11.870 回答
0

除了 ouah 发布的内容之外,我认为您应该检查 malloc() 返回的指针值。您可能无法分配您请求的内存量。

于 2013-02-27T23:43:33.880 回答