简体   繁体   English

C(linux)传递结构数组以删除元素

[英]C (linux) passing array of structs to delete element

I have the following issues in my C Program, 我的C程序中存在以下问题,

FIRST, I have the following 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;
}

For debugging I loop through and print the values in the array of structs - this works (nevermind I'm not returning a value in this function - the 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 BOOM - 段错误

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 kind of 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) 工作正常......(tempex现在在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

I am getting errors here. 我在这里得到错误。 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
  //realloc if needed - gotta get here first - pass segfault and/or jumbled data

  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 only allocated one struct, not 3 as you think. 您只分配了一个结构,而不是您想象的3。

You should do something like : 你应该做的事情如下:

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

What you do is OK with the const char (string literal) assignments. 使用const char (字符串文字)赋值可以做什么。 But you should change your definition of struct ts to: 但是你应该将struct ts的定义更改为:

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

This way your compiler will warn you if you try to change the contents of those strings. 这样,如果您尝试更改这些字符串的内容,编译器将发出警告。

Otherwise you can use malloc() and strcpy() for your char* 's in the struct .And 否则,您可以在struct .And中使用malloc()strcpy()作为char*

ex[0].fname = malloc(sizeof(char) * 128);
//...
strcpy(ex[0].fname , "myString");
//...

Also : 另外:

This code snippet looks a bit weird 这段代码看起来有点奇怪

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

  for(i=0; i<sizeof(passedex)-1; i++){
      //...
  }
  return;
}

I think you mean 我想你的意思是

void delelement(char *delwhat, struct ts *passedex , int array_size)
{
    int i;
    for( i=0 ; i < array_size ; i++ )
    {
         //...

You need to pass the size of the array as an argument. 您需要将数组的大小作为参数传递。 You may find some posts on this link interesting : newbie questions about malloc and sizeof 你可能会在这个链接上发现一些有趣的帖子: 关于malloc和sizeof的新手问题

you are allocating space only for one ts struct 你只为一个ts结构分配空间

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

fact that you can access and work fine with the memory after your allocated space it's just pure luck 事实上,你可以在分配空间后访问和处理内存,这只是纯粹的运气

Next problem: 下一个问题:

for(i=0; i<sizeof(passedex)-1; i++){

The sizeof operator does not return the number of element in an array, it returns the number of bytes one passedex occupies. sizeof运算符不返回数组中的元素数,它返回一个 passedex占用的字节数。 As this is a pointer, it will have a value like 4 or 8, depending on the kind of machine you are using. 由于这是一个指针,它将具有类似4或8的值,具体取决于您使用的机器类型。

In fact, in C, there is no way of knowing how big an array, if all you have is a pointer to it. 实际上,在C语言中,没有办法知道数组有多大,如果只有指向它的指针。 This means that you have to pass in new parameter informing your routine how big the array is. 这意味着您必须传入新参数,通知您的例程数组有多大。

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

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