3

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. 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

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. 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.

2
  • One error possibly is that you are allocating memory just for 1 struct, but then trying to fill 3 elements. Instead should be struct ts *ex=(struct ts*)malloc(3*sizeof(struct ts)); Commented Mar 29, 2011 at 16:04
  • Same user duplicate : stackoverflow.com/questions/5474925/… Commented Mar 29, 2011 at 16:15

2 Answers 2

1

You're only allocating enough space in your ex array for a single struct:

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Edit: Also, if you're on a linux platform, look into valgrind.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.