C (linux) передача массива структур для удаления элемента - PullRequest
1 голос
/ 29 марта 2011

У меня есть следующие проблемы в моей программе на C,

FIRST, у меня есть следующая структура,

#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;
}

Для отладки я перебираю и печатаю значения в массиве структур- это работает (не берите в голову, что я не возвращаю значение в этой функции - проблема, с которой я сталкиваюсь, заключается в том, что мы до этого даже не добрались).

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;
}

теперь ЭТО работает нормально - печатает информацию правильно.

теперь давайте просто удалим комментарий и определим временный массив структур

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

ОК, поэтому япопробовал другой подход - какой тип работ

#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;
}

РАБОТАЕТ нормально ... (теперь 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

теперь позволяет начать присваивать значения * tempex - без segfaultс tempex, определенным в main

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;
}

, но СЕЙЧАС - странность

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

Я получаю ошибки здесь.Цель состоит в том, чтобы иметь динамический массив структур, содержащих символы char *.После того, как эта проблема будет решена, в main (или где бы то ни было) будет экземпляр, который я хочу удалить одну из этих структур.

То, к чему я стремился, было что-то вроде

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;
}

Таким образом, он создаст (или будет иметь) временный массив структур для работы ... загрузит этот массив минус тот, который будет удален ... перезагрузит переданный массив структур и передаст его обратно.

Ответы [ 3 ]

2 голосов
/ 29 марта 2011

Вы выделили только одну структуру, а не 3, как вы думаете.

Вы должны сделать что-то вроде:

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

То, что вы делаете, в порядке с const char (строковый литерал)задания.Но вы должны изменить определение struct ts на:

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

Таким образом, ваш компилятор предупредит вас, если вы попытаетесь изменить содержимое этих строк.

В противном случае вы можете использовать malloc() и strcpy() для своих char* в struct. И

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

Также:

Этот кодфрагмент выглядит немного странно

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

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

Я думаю, вы имеете в виду

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

Вам нужно передать размер массива в качестве аргумента.Вы можете найти некоторые сообщения по этой ссылке интересными: вопросы новичка о malloc и sizeof

1 голос
/ 29 марта 2011

Следующая проблема:

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

Оператор sizeof не возвращает номер элемента в массиве, он возвращает количество байтов one занимаемых passedex. Поскольку это указатель, он будет иметь значение, подобное 4 или 8, в зависимости от типа используемой машины.

На самом деле, в C нет способа узнать, насколько велик массив, если у вас есть только указатель на него. Это означает, что вы должны передать новый параметр, сообщающий вашей программе, насколько велик массив.

1 голос
/ 29 марта 2011

Вы выделяете место только для одной структуры TS

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

тот факт, что вы можете получить доступ и работать с памятью после того, как вам выделено место, это просто удача

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...