Помощь: Вставка элементов в массив в C! - PullRequest
0 голосов
/ 18 июля 2011

Вот мой код для объединения уникальных элементов из массива B в массив A.

Например:

Ввод: A={1, 3, 5, 7, 9}, B={2, 4, 6, 9}

Выход: A={1, 2, 3, 4, 5, 6, 7, 9}

Но я получил ошибку сегментации в строке 46. Я предполагаю, что это проблема с массивом, но не смог ее решить. Есть идеи?


#include <stdio.h>
#define MAXSIZE 100
typedef int ElemType;
typedef struct{
    ElemType data[MAXSIZE];
int length;
}SqList;

void CreateList(SqList *L, int n){
L->length=n;
printf("\ninput %d data: ", n);
int i;
for(i=0;i<n;i++)
    scanf("%d", &L->data[i]);
}   

void PrintList(SqList *L){
int i;
int n;
n=L->length;
printf("\noutput %d data: ", n);
for(i=0;i<n;i++)
    printf("%d", L->data[i]);
}


ElemType GetElem(SqList *L,int i){
return L->data[i];
}

int LocateElem(SqList *L, ElemType e){
int i;
for(i=1;i<=L->length;i++){
    if(L->data[i]==e){
       return i;
       break;
    }
    else return 0;
}
}

void ListInsert(SqList *L, ElemType e){
int n = L->length;
n++;
L->length=n;     
L->data[n]=e;                        // Segmentation Fault Here !
}


void merge(SqList *La, SqList *Lb){
int i;
ElemType e;
for(i=0;i<Lb->length;i++){
    e=GetElem(&Lb,i);   
    if(!LocateElem(&La,e))
        ListInsert(&La,e);
}
}

int main(){
SqList La,Lb;
int n1,n2;
printf("\nInput number for La: ");
scanf("%d",&n1);
CreateList(&La,n1);
printf("\nInput number for Lb: ");
scanf("%d",&n2);
CreateList(&Lb,n2);
printf("Here is La:\n");
PrintList(&La);
printf("Here is Lb:\n");
PrintList(&Lb);
merge(&La,&Lb);
printf("Here is merged list:\n");
PrintList(&La);

return 0;
}

Ответы [ 5 ]

2 голосов
/ 18 июля 2011

Вы используете & слишком много в merge коде

void merge(SqList *La, SqList *Lb){
  int i;
  ElemType e;
  for(i=0;i<Lb->length;i++){
    e=GetElem(Lb,i);   
    if(!LocateElem(La,e))
      ListInsert(La,e);
  }
}

, тогда это не вызывает ошибки, но я не проверял, правильна ли "логика" (полагаю, это)

Добавить

Также необходимо исправить ListInsert:

void ListInsert(SqList *L, ElemType e){
  int n = L->length;
  L->data[n]=e;
  L->length++;
}

Ваша версия пропускает элемент массива, так как вы используете "«увеличенный размер» для индексации нового элемента, в то время как новое вставленное значение должно быть помещено в индекс L->length, а затем вам нужно увеличить длину массива (последний элемент массива размера N равен N-1, поэтому увеличивающий размерN + 1, последний элемент будет иметь индекс N).

Конечно, вы не проверяете границы массива, поэтому вы можете столкнуться с проблемами, если вставите больше, чем элементы MAXSIZE.

Добавить 2

Ваш LocateElem тоже нуждается в исправлении:

int LocateElem(SqList *L, ElemType e){
  int i;
  for(i=1;i<=L->length;i++){
    if(L->data[i]==e){
      return i;
    }
  }
  return 0;
}

(я сохранил вашу идею использовать 0 в качестве специального значения для not found, хотя читал комментарий об этоми речь MAXSIZE, более того, необходимо исправлять большую часть вашего кода, чтобы использовать его последовательно).Здесь исправление касается того факта, что вы вернулись, когда обнаружили, что первый элемент не равен e, в то время как (я полагаю) вы хотите вернуть 0, если вы не найдете элемент, или что-то не-0, если вы его нашли.Этот фиксированный код исследует весь массив (начиная с 1, если вы зарезервировали индекс 0 для специального значения)

1 голос
/ 18 июля 2011

если длина равна n, то должны использоваться только элементы от 0 до n-1. Конечно, вы могли бы также писать мимо MAXLIST-1. Вы должны всегда добавлять код для проверки, чем L-> length <= MAXLIST. </p>

Мне действительно интересно, почему вы выбрали этот довольно сложный подход. И я бы переименовал ListInsert в ListAppend, так как вы добавляете только в конец списка.

1 голос
/ 18 июля 2011

Вы должны убедиться, что n не превышает MAXSIZE.Ошибка сегментации, скорее всего, вызвана переполнением буфера.

0 голосов
/ 18 июля 2011

Функция LocateElem выглядит мне глючной.Почему он возвращает 0, если первый тест в цикле не проходит?А почему перерыв после возврата заявления?Несколько строк были перетасованы, кажется ... разрыв должен идти, а возврат 0 перемещается после блока for.

0 голосов
/ 18 июля 2011

Вот несколько ошибок, которые могут быть причиной вашей проблемы:

int LocateElem(SqList *L, ElemType e){
int i;
for(i=1;i<=L->length;i++){
    if(L->data[i]==e){           // <-- You need to check data[i-1]
       return i;                 //     since you span [1,length] (off by one)
       break;
    }
    else return 0;               // <-- This goes to outside of the loop,
}                                //     otherwise only the first item is queried
}

void ListInsert(SqList *L, ElemType e){
int n = L->length;
n++;
L->length=n;     
L->data[n]=e;                    // <-- You want to modify data[n-1]
}                                //     since n is already incremented here
...