2013-02-27 1 views
1

Вот код в вопросе:Неверный размер записи 4

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. 

Я считаю, что ошибка должна быть как я таНос, но я не являюсь так уверен. Значение ARGV [1] является 600851475143.

+2

Я откатил правки. Исправление исходного (ошибочного) фрагмента сделало бы (правильные) ответы бесполезными, ИМО. – wildplasser

ответ

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 */ 
} 

И не пытайтесь выделять 1 ТБ за один раз ...

+0

Да, я думаю, мне нужно будет понять это с помощью другого алгоритма. Благодаря! –

5

Массивы 0 -origin в C:

i <= prime_limit; 

должен быть

i < prime_limit; 

В противном случае atol не является безопасным и не может сделать обнаружение ошибок. Используйте strtol, чтобы преобразовать строку в long.

+0

Тот факт, что это 0 происхождение, не имеет значения, потому что я не рассчитываю с 0, я рассчитываю от 2. –

+1

@EduardoB. То, что это «0» - начало, означает, что последний элемент массива «primes [prime_limit - 1] ', а не' primes [prime_limit] '. – ouah

+0

Хорошо, это имеет смысл. Но я все равно получаю ту же ошибку. –

0

В дополнение к тому, что было опубликовано, я думаю, вы должны проверить значение указателя, возвращаемое malloc(). Возможно, вы не смогли выделить объем запрошенной вами памяти.

+0

primes == NULL возвращает true. Итак, я думаю, что есть проблема с malloc? –

+1

С другой стороны, вы сказали 'prime_limit = 300425737571'. Поскольку 'sizeof (int)' равно 4 байтам, объем памяти, который вы, похоже, пытаетесь выделить, немного превышает 1 ТБ. Так что вам, вероятно, не хватает памяти. – MysticXG

 Смежные вопросы

  • Нет связанных вопросов^_^