Реаллок x86 x86_64

у меня есть функция

void *srealloc(void * ptr , int size){
    void *tmp = realloc(ptr , size);
    if(tmp == NULL){
        fprintf(stderr,"realloc of %u bytes failed", size);
        exit(1);
    }
    return tmp;
}

Мой код, который вызывает это, отлично работает на компьютере с архитектурой x86, но когда я компилирую и запускаю тот же код на своем компьютере с архитектурой x64, я получаю segfault.

Пример того, как это называется:

line = "Some string";
buffer = (char**) srealloc (buffer,sizeof(buffer)*(++buffer_lines));
buffer[buffer_lines-1] = line;

Когда я трассирую с помощью gdb, когда srealloc вызывается на компьютере с ошибкой сегментации ptr == 0x0, size == 8

* Редактировать: ошибка сегментации возникает:

void *tmp = realloc(ptr, size);

person LeeG    schedule 25.11.2011    source источник
comment
Обратите внимание, что sizeof(buffer) — это размер указателя на указатель на char. Чтобы быть правильным, вы должны использовать sizeof(char *). Здесь это не имеет особого значения, поскольку размер указателя на один тип такой же, как и указатель на другой тип, просто хотел указать на это.   -  person Some programmer dude    schedule 25.11.2011
comment
буфер — это глобальная переменная: char **buffer = NULL;   -  person LeeG    schedule 25.11.2011
comment
@JoachimPileborg Хорошо, изначально у меня был такой код, но в какой-то момент он был изменен из-за разочарования.   -  person LeeG    schedule 25.11.2011
comment
Вероятно, это не связано с вашим сбоем, но ваша функция также имеет неправильную подпись, она должна иметь такую ​​​​же, как и сама realloc. int не является правильным типом для размеров, никогда не используйте подписанный тип для такой цели. В частности, в современных 64-битных архитектурах int обычно составляет только 32 бита, а size_t — 64. Используйте size_t, он предназначен для таких вещей.   -  person Jens Gustedt    schedule 25.11.2011


Ответы (2)


Ваш звонок выглядит нормально. Сбой в malloc(), realloc(), calloc() или free() часто является признаком ошибки где-то еще в вашей программе, где вы записали за пределы выделенного блока и топтались по служебной информации, используемой функциями распределения памяти.

Попробуйте запустить свою программу с помощью такого инструмента, как Valgrind или Purify.

person caf    schedule 25.11.2011
comment
После запуска Valgrind оказалось, что у меня был strncpy(cp,line,strlen(line)+1), когда cp* не был инициализирован. Я предполагаю, что позже это приведет к разгрому, когда я вызову realloc. Валгринд был хорошим выбором. - person LeeG; 25.11.2011

Убедитесь, что код, вызывающий realloc, имеет допустимый прототип для этой функции (другими словами, включите stdlib.h).

Многие проблемы при переключении с 32 на 64 бита связаны с несоответствием между целыми числами (аргументами по умолчанию, если нет прототипа) и указателями. В то время как целые числа могут оставаться 32-битными на 64-битной платформе, указатели могут быть увеличены в размере.

Поскольку вы указываете, что указатель имеет значение NULL, а запрошенный размер равен 8, это, безусловно, правильное использование функции. Перераспределение нулевого указателя фактически такое же, как и malloc. Вот почему я подозреваю проблему с прототипом.

Также убедитесь, что вы компилируете все на новом компьютере. Вы можете столкнуться с проблемами, если попытаетесь скомпилировать 32-битный srealloc с 64-битным клиентом.

person paxdiablo    schedule 25.11.2011
comment
После запуска Valgrind выясняется, что отправка указателя мусора на strncpy() испортила мою кучу. Это не объясняет, почему мой код работал на компьютере x86, но я рад, что нашел причину этой ошибки. - person LeeG; 25.11.2011