2014-11-28 3 views
1

У меня есть функция, которая копирует часть массива (от первого до последнего) в новый массив. Когда я запустил код, я закончил сбой. Я знаю, что seg ошибки происходят, когда я не выделяю достаточно места для массива или когда я пытаюсь получить доступ к памяти, которая не была выделена. Но для моей len я уже установил ее как last-first + 1, которой должно быть достаточно, чтобы охватить часть массива, которую я хочу скопировать. Но почему это все еще дает мне ошибку? Или я чего-то не хватает?Ошибка сегментации при копировании части массива в c

Вот структура для моего кода я сделал:

typedef struct { 
    int* data; 
    unsigned int len; 
} intarr_t; 

Вот функцию, чтобы скопировать часть массива в новый один:

intarr_t* intarr_copy_subarray(intarr_t* ia, 
       unsigned int first, 
       unsigned int last) 
{ 
    unsigned int len = last-first+1; 
    intarr_t* newia = malloc(sizeof(intarr_t)); 
    assert (newia); 
    newia->data = malloc(sizeof(int)*len); 
    assert (newia->data); 
    newia->len = len; 
    if (newia == 0 || ia == NULL || last < first) 
    { 
     return NULL; 
    } 
    else 
    { 
     for (int x = first; x <= last; x++) 
     { 
      memcpy (newia->data[x], ia->data[x], (len*sizeof(int))); 
     } 
     return newia; 
    } 
    free (newia); 
    return 0; 
} 
+1

'assert (newia);' 'assert (newia-> data);' Это плохо. Используйте 'assert' только для обнаружения логических ошибок, а не для совершенно нормальных условий. (Если вы это сделаете, вы найдете по крайней мере одну причину ошибки сегментации.) Кроме того, у вас есть утечка памяти (в двух из трех случаев), если выполняется «return NULL;». – Deduplicator

+0

@Deduplicator Да, это было упомянуто ранее. Я изменил его, чтобы проверить, является ли ia == NULL и последним <первым первым, прежде чем я выделил какую-либо память, а затем, если условие выше IS null, я установил его для возврата NULL и free (ia). Это хороший подход к этому? –

ответ

1

Изменить эти заявления

for (int x = first; x <= last; x++) 
    { 
     memcpy (newia->data[x], ia->data[x], (len*sizeof(int))); 
    } 

до

memcpy (newia->data, ia->data + first, len * sizeof(int)); 

или

for (unsigned int i = 0; i < len; i++) 
    { 
     newia->data[i] = ia->data[i + first]; 
    } 

Также это условие

if (newia == 0 || ia == NULL || last < first) 
{ 
    return NULL; 
} 

является ошибочным. Вы должны освободить выделенную память в этом блоке, если первая из них равна NULL или последней <.

Перед распределением памяти необходимо проверить эти условия.

+0

О, цикл for не нужен? Я думал, что для этого нужно сначала перебрать массив из индексов, чтобы скопировать элементы в этих индексах. –

+1

@John Claser Либо используйте memcpy или loop, как я показал. –

1

Это проблема с оператором memcpy, который у вас есть в цикле for. Пожалуйста, обратите внимание, что когда вы даете newia-> data [x], он получает преобразование в целочисленное значение на этом конкретном указателе.

Так, например, данные, указывающие на целочисленной переменной со значением, как newia-> данных [х] = 2 и второй, как в другое целое число переменных ia-> данные [х] = 3, то ваш тетсру становится

memcpy (2, 3, len * sizeof (int));

Так эффективно, что вы заканчиваете копирование данных с адреса 3 на адрес 2, для которого оба не выделены вами.

Вам необходимо следовать по предложению Влада из Москвы.

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