Segfault с перераспределением - PullRequest
       13

Segfault с перераспределением

0 голосов
/ 05 октября 2011

Таким образом, я использовал malloc в своей программе, а затем realloc внутри метода внутри программы. После того, как я вызывал этот метод много раз, я получал «Ошибка сегментации (ядро сброшено)».

При дальнейшей проверке я понял, что по какой-то причине, когда мой указатель переходит от 0x25d7d60 или 0x223fae0 (или любого адреса, представленного 7 цифрами (0xHHHHHHHH)) к 0x7f47d370a010 (с более чем 7 цифрами), например, из-за ошибки генерируется ошибка изнутри вызов realloc, realloc даже не вернет NULL. Я исправил это, просто используя malloc, а затем memcpy. Однако я очень смущен тем, почему это произошло, и хотел посмотреть, сможет ли кто-нибудь из пользователей stackoverflow пролить некоторый свет на то, почему это произошло.

Спасибо

Вот соответствующий код:

 unsigned int* myArray;
 unsigned int num_ints;

 int main()
 {

   num_ints = 100; 
   if((myArray =(unsigned int*) malloc(sizeof(unsigned int)*(num_ints)*3))==NULL)
   {
    std::cout << "Malloc failed!" << std::endl;
    return false;
   }

   .
   .
   .

   //This called when n key is pressed (code left out)
   methodName();
 return true;
 }

 void methodName()
 {

 if((myArray =(unsigned int*) realloc(myArray,sizeof(unsigned int)*(num_ints*4)*3))==NULL)
 {
    std::cout << "Realloc failed!" << std::endl;
    exit(0);
 }

 }

Ответы [ 4 ]

5 голосов
/ 05 октября 2011

Есть большая вероятность, что, вызывая "realloc внутри метода внутри программы", вы фактически загружаете его в локальную переменную, которая затем выбрасывается, и ваша программа продолжает использовать старый указатель (который теперь былосвобожден).

Нам бы хотелось, чтобы код был определенным, но, по моему опыту, это одна из основных причин ошибок выделения.


На основании того, что вы 'показали, нет ничего плохого в том, что ты делаешь.По сути, он такой же, как этот код:

#include <iostream>
#include <cstdlib>
int sz = 1000;
int *buffer = 0;
static int methodName (void) {
    if (sz == 100000)
        sz = 100;
    sz = sz * 10;
    if ((buffer = (int*)realloc (buffer, sz)) == 0) {
        std::cout << "Realloc error" << std::endl;
        return 1;
    }
    return 0;
}
int main(void) {
    int i;
    if ((buffer = (int*)malloc (sz)) == 0) {
        std::cout << "Alloc error" << std::endl;
        return 1;
    }
    for (i = 0; i < 10000000; i++)
        if (methodName() != 0)
            return 1;
    std::cout << "All okay" << std::endl;
    return 0;
}

, который отлично работает, выполняя десять миллионов перераспределений.

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

3 голосов
/ 05 октября 2011

Если realloc меняет адрес массива, то myarr в области действия функции (локальная) получает новое значение, оно не меняет переменную myarr в main

* 1006.*
0 голосов
/ 05 октября 2011

Проблема в том, что ваша функция methodName назначает новый указатель для своей локальной копии myArray.

Быстрое решение состоит в том, чтобы сделать myArray указателем на указатель следующим образом:

void methodName(unsigned int **myArray, unsigned int num_ints)
{
    if((*myArray = (unsigned int *)realloc((*myArray), sizeof(unsigned int)*(num_ints*4)*3)) == NULL)
    {
        std::cout << "Realloc failed!" << std::endl;
        exit(0);
    }
}

, а затем позвоните, передав адрес myArr:

methodName(&myArr, n_ints);

Таким образом methodName получает адрес памяти main() s myArr, чтобы он мог писать в него.

Однако, как вы можете видеть, наличие параметров функции, которые выводят значения, может стать немного запутанным, поэтому я предлагаю вместо этого return новый адрес:

unsigned int *methodName(unsigned int *myArray, unsigned int num_ints)
{
    return (unsigned int *)realloc(myArray, sizeof(unsigned int) * (num_ints * 4) *3); 
}

Тогда это просто вопрос перезаписи myArr в main:

myArr = methodName(myArr, n_ints);
0 голосов
/ 05 октября 2011

Вы не изменили myArr в основной области видимости, realloc может вернуть новый адрес, старый адрес недействителен.

...