简体   繁体   English

c传递结构数组并删除一个

[英]c passing array of structs and delete one

OK - please be patient for long winded explanation - I assume this is something just completely stupid on my part, because it's been (several) years since working in c. 好的 - 请耐心等待冗长的解释 - 我认为这对我来说是完全愚蠢的,因为自从在c工作以来已经过了好几年了。 I have a couple of weird issues that I'm dealing with. 我有几个奇怪的问题,我正在处理。

FIRST: 第一:

Have structure 有结构

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct ts{
  char *fname;
  char *lname;
  char *fingers;
  char *toes;
};

void delelement(char *, struct ts *);
int i;

int main(int argc, char **argv){
  struct ts *ex=(struct ts*)malloc(sizeof(struct ts));

  ex[0].fname="joe";
  ex[0].lname="bob";
  ex[0].fingers="11";
  ex[0].toes="9";

  ex[1].fname="billy";
  ex[1].lname="bronco";
  ex[1].fingers="10";
  ex[1].toes="10";

  ex[2].fname="martha";
  ex[2].lname="sue";
  ex[2].fingers="12";
  ex[2].toes="20";

  delelement("billy", ex);

  return 0;
}

now we get to the part I'm having problems with. 现在我们到达了我遇到问题的部分。 now for debugging I loop through and print out the values in the array of structs - this works (nevermind I'm not returning a value in this function - problem I'm running into is before we even get to that) 现在用于调试我循环并打印出结构数组中的值 - 这是有效的(没关系,我没有在这个函数中返回一个值 - 我遇到的问题是在我们开始之前)

void delelement(char *delwhat, struct ts *passedex){

  //struct ts *tempex=(struct ts*)malloc(sizeof(struct ts));
  for(i=0; i<sizeof(passedex)-1; i++){
    printf("passedex[%d].fname is %s\n", i, passedex[i].fname);    
    printf("passedex[%d].lname is %s\n", i, passedex[i].lname);
    printf("passedex[%d].fingers is %s\n", i, passedex[i].fingers);
    printf("passedex[%d].toes is %s\n", i, passedex[i].toes);
  }
  return;
}

now THAT works fine - prints out information correctly. 现在工作正常 - 正确打印信息。

now let's simply remove the comment and define the temporary array of structs 现在让我们简单地删除注释并定义临时结构数组

void delelement(char *delwhat, struct ts *passedex){

  struct ts *tempex=(struct ts*)malloc(sizeof(struct ts));
  for(i=0; i<sizeof(passedex)-1; i++){
    printf("passedex[%d].fname is %s\n", i, passedex[i].fname);    
    printf("passedex[%d].lname is %s\n", i, passedex[i].lname);
    printf("passedex[%d].fingers is %s\n", i, passedex[i].fingers);
    printf("passedex[%d].toes is %s\n", i, passedex[i].toes);

  }
  return;
}

BOOM - segfault
passedex[0].fname is joe
passedex[0].lname is bob
passedex[0].fingers is 11
passedex[0].toes is 9
passedex[1].fname is billy
Segmentation fault

OK so I tried a different approach - which kinda works 好的,所以我尝试了一种不同的方法 - 哪种方法有效

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct ts{
  char *fname;
  char *lname;
  char *fingers;
  char *toes;
};

void delelement(char *, struct ts *, struct ts *);
int i;

int main(int argc, char **argv){
  struct ts *ex=(struct ts*)malloc(sizeof(struct ts));
  struct ts *tempex=(struct ts*)malloc(sizeof(struct ts));

  ex[0].fname="joe";
  ex[0].lname="bob";
  ex[0].fingers="11";
  ex[0].toes="9";

  ex[1].fname="billy";
  ex[1].lname="bronco";
  ex[1].fingers="10";
  ex[1].toes="10";

  ex[2].fname="martha";
  ex[2].lname="sue";
  ex[2].fingers="12";
  ex[2].toes="20";

  delelement("billy", ex, tempex);

  return 0;
}

void delelement(char *delwhat, struct ts *passedex, struct ts *tempex){

  //struct ts *tempex=(struct ts*)malloc(sizeof(struct ts));

  for(i=0; i<sizeof(passedex)-1; i++){
    printf("passedex[%d].fname is %s\n", i, passedex[i].fname);    
    printf("passedex[%d].lname is %s\n", i, passedex[i].lname);
    printf("passedex[%d].fingers is %s\n", i, passedex[i].fingers);
    printf("passedex[%d].toes is %s\n", i, passedex[i].toes);
  }
  return;
}

WORKS fine... (tempex now defined in main)
passedex[0].fname is joe
passedex[0].lname is bob
passedex[0].fingers is 11
passedex[0].toes is 9
passedex[1].fname is billy
passedex[1].lname is bronco
passedex[1].fingers is 10
passedex[1].toes is 10
passedex[2].fname is martha
passedex[2].lname is sue
passedex[2].fingers is 12
passedex[2].toes is 20

now lets start assigning values to *tempex - no segfault with tempex defined in main 现在让我们开始为* tempex分配值 - 没有在main中定义的tempex的段错误

void delelement(char *delwhat, struct ts *passedex, struct ts *tempex){

  //struct ts *tempex=(struct ts*)malloc(sizeof(struct ts));

  for(i=0; i<sizeof(passedex)-1; i++){
    printf("passedex[%d].fname is %s\n", i, passedex[i].fname);    
    printf("passedex[%d].lname is %s\n", i, passedex[i].lname);
    printf("passedex[%d].fingers is %s\n", i, passedex[i].fingers);
    printf("passedex[%d].toes is %s\n", i, passedex[i].toes);
    tempex[i].fname=passedex[i].fname;
    tempex[i].lname=passedex[i].lname;
    tempex[i].fingers=passedex[i].fingers;
    tempex[i].toes=passedex[i].toes;
  }
  return;
}

but NOW - weirdness

passedex[0].fname is joe
passedex[0].lname is bob
passedex[0].fingers is 11
passedex[0].toes is 9
passedex[1].fname is billy
passedex[1].lname is bronco
passedex[1].fingers is joe
passedex[1].toes is bob
passedex[2].fname is 11
passedex[2].lname is 9
passedex[2].fingers is billy
passedex[2].toes is bronco

obviously I'm just missing something stupid, or understanding this wrong, but have now dug a rut that I can't get out of. 显然我只是错过了一些愚蠢的东西,或者理解这个错误,但现在已经挖了一个我无法摆脱的辙。 Any help would be appreciated. 任何帮助,将不胜感激。

The goal is to have a dynamic array of structures containing char *'s. 目标是拥有一个包含char *的动态结构数组。 Once past this issue, there will be an instance in main (or wherever) that I wish to delete one of those structures. 一旦过了这个问题,主要(或任何地方)将有一个实例我希望删除其中一个结构。

What I was going for was something like... 我想要的是......

struct ts* delelement(char *delwhat, struct ts *passedex, struct ts *tempex){

  //struct ts *tempex=(struct ts*)malloc(sizeof(struct ts));

  for(i=0; i<sizeof(passedex)-1; i++){
    printf("passedex[%d].fname is %s\n", i, passedex[i].fname);    
    printf("passedex[%d].lname is %s\n", i, passedex[i].lname);
    printf("passedex[%d].fingers is %s\n", i, passedex[i].fingers);
    printf("passedex[%d].toes is %s\n", i, passedex[i].toes);
    //load tempex with everything except the one I want to delete
    if(!(passedex[i].fname==delwhat)){
      tempex[i].fname=passedex[i].fname;
      tempex[i].lname=passedex[i].lname;
      tempex[i].fingers=passedex[i].fingers;
      tempex[i].toes=passedex[i].toes;
    }
  }
  free(passedex); //haven't got here yet - dunno if needed

  for(i=0; i<sizeof(passedex)-1; i++){
    passedex[i].fname=tempex[i].fname;
    passedex[i].lname=tempex[i].lname;
    passedex[i].fingers=tempex[i].fingers;
    passedex[i].toes=tempex[i].toes;
  }

  return passedex;
}

so it would create (or have) a temporary array of structs to work with... load that array minus the one to be deleted... reload the passed array of structs and pass it back. 因此它会创建(或拥有)一个临时的结构数组来处理...加载该数组减去要删除的数组...重新加载传递的结构数组并将其传回。

You're only allocating enough space in your ex array for a single struct: 您只需在ex数组中为单个结构分配足够的空间:

struct ts *ex=(struct ts*)malloc(sizeof(struct ts));

ex[0].fname="joe";
ex[0].lname="bob";
ex[0].fingers="11";
ex[0].toes="9";

But now you write beyond the end of the array: 但现在你写的超出了数组的末尾:

ex[1].fname="billy";
ex[1].lname="bronco";
ex[1].fingers="10";
ex[1].toes="10";

I guess then your heap check routine causes the segfault when you try to allocate new memory and it finds you've corrupted it. 我想当你尝试分配新的内存时,你的堆检查例程会导致段错误,并且它发现你已经破坏了它。

You're not allocating enough memory for an array of structs, only for a single entry. 您没有为结构数组分配足够的内存,仅用于单个条目。 Try this instead: 试试这个:

struct ts *ex=(struct ts*)malloc(sizeof(struct ts) * 3);

Where 3 is the number of array elements. 其中3是数组元素的数量。

Edit: Also, if you're on a linux platform, look into valgrind. 编辑:此外,如果你在Linux平台上,请查看valgrind。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM