LINUX.ORG.RU

Glibs bug или я не прав

 , ,


0

1

Gentoo ~amd64. Решил покопаться в C'ях. Задача следущая, написать расширяемый массив. Во время исследований этой темы получил следующий прикол.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#define N 4
#define LINE 10

int main(void)
{
    int **array;
    int i;

    array = (int **)malloc(sizeof(int) * N);
    for (i=0;i<N;i++)
    {
        array[i] = (int *)malloc(sizeof(int) * LINE);
    }

    for (i=0;i<N;i++)
    {
        array[i] = (int *)realloc(array[i], sizeof(int) * LINE * 2);
    }

    return 0;
}

На моей тачке получаю

*** glibc detected *** /tmp/untitled/untitled: realloc(): invalid old size: 0x0000000000602030 ***

(gdb) bt
#0  0x00007ffff72e8ac5 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x00007ffff72e9f46 in *__GI_abort () at abort.c:93
#2  0x00007ffff7323f67 in __libc_message (do_abort=2, fmt=0x7ffff74045d8 "*** glibc detected *** %s: %s: 0x%s ***\n")
    at ../sysdeps/unix/sysv/linux/libc_fatal.c:198
#3  0x00007ffff7329496 in malloc_printerr (action=3, str=0x7ffff74018bb "realloc(): invalid old size", ptr=<optimized out>) at malloc.c:6283
#4  0x00007ffff732cf6c in _int_realloc (av=0x7ffff763dea0, oldp=0x602020, oldsize=6299840, nb=96) at malloc.c:5238
#5  0x00007ffff732e489 in *__GI___libc_realloc (oldmem=0x602030, bytes=80) at malloc.c:3821
#6  0x0000000000400661 in main () at main.c:21

Есть домашний сервачек с Archlinux'ом, там собрал это дело, все отработало без glibc detected. В чем прикол, подскажите?



Последнее исправление: cetjs2 (всего исправлений: 2)
Ответ на: комментарий от vaino

А можно поподробнее? Я касты сделал чтобы оно собралось на ArchLinux'е. Орал типо не могу преобразовать из void* в int**.

А на генту у меня все нормально что с кастом что без него собирается.

libbkmz
() автор топика
Ответ на: комментарий от libbkmz

А на генту у меня все нормально что с кастом что без него собирается.

ты должен выделить память под int*, а выделяешь размером как для int, на 32 бит размеры их равны, а на 64 бит - int в два раза меньше указателя

vaino
()
Ответ на: комментарий от libbkmz

Потому что ты выделяешь место под массив указателей.

UVV ★★★★★
()

Не то что бы я знал С... а ничего, что при выделении памяти в первый раз sizeof(int)*N != sizeof(int*)*N ? Ну во всяком случае для 64 разр. платформы? Соответственно Вы при инициализации array начиная с i>N/2 вылезаете за выделенную область памяти, со всеми вытекающими.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Тьфу-ты, тут видать кто-то из списка друзей моих отписался, а я и не вижу...

AIv ★★★★★
()
Ответ на: комментарий от Reset

чтобы словить сегфолт еще раньше ? :)


Это с чего-бы? Взятие адреса указателя - всё ок. Я просто почему-то подумал, что приводить к указателю на указатель нельзя, оказывается можно.

Dragon59 ★★
()
Ответ на: комментарий от Dragon59

во-первых, твой вариант не скомпилируется. во-вторых, если и скомпилируется, то при первом же обращении array ты запишешь неизвестно что неизвестно куда.

Reset ★★★★★
()
16 апреля 2014 г.

На 64х-битных платформах sizeof(int) != sizeof(int*).

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.