帮助:在C中将元素插入数组!

时间:2011-07-17 20:20:48

标签: c arrays segmentation-fault

以下是将数组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 个答案:

答案 0 :(得分:2)

您在&代码

中使用了一些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作为未找到的特殊值的想法,尽管阅读了关于它的评论和MAXSIZE语言;此外,您的更多代码需要修复才能始终如一地使用它)。这里的修复是关于当你发现第一个元素不等于e时返回的事实,而(我想)你想要返回0如果没有找到元素,或者如果你找到它则不返回-0。这个固定的代码探索整个数组(从1开始,如果保留0索引以获得特殊含义)

答案 1 :(得分:1)

您必须检查n是否超过MAXSIZE。分段错误很可能是由缓冲区溢出引起的。

答案 2 :(得分:1)

如果长度为n,则只应使用0到n-1的元素。当然你也可以写过MAXLIST-1。您应该始终添加要检查的代码,而不是L-&gt;长度&lt; = MAXLIST。

我很想知道你为什么选择这种相当复杂的方法。我会将ListInsert重命名为ListAppend,因为您只添加到列表的末尾。

答案 3 :(得分:0)

以下是可能导致问题的一些错误:

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

答案 4 :(得分:0)

LocateElem函数看起来很麻烦。如果循环中的第一个测试失败,为什么它返回0?为什么在退货声明后休息?看起来有几行被洗牌......休息应该去,并且在阻止之后返回0。