写入大小无效4

时间:2013-02-27 23:08:55

标签: c memory-management valgrind

以下是相关代码:

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。

3 个答案:

答案 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()返回的指针值。您可能无法分配所请求的内存量。