abitlost
abitlost

Reputation: 5

Allocating a fixed sized object to a pointer (pointing to a struct) without using malloc

I have a pointer to a struct list* ptr The struct contains a char and a pointer to the next struct and these are used for an array of structures like so:

list array[setSize]; //setSize is defined as 20 

Without using malloc, I need to initialize list* ptr so that it has all the elements of the array.

I have tried the following and I get a segmentation fault. I believe I am utterly misunderstanding how pointers work. (I haven't touched C in a long while)

int j = 0;
ptr = sizeof(array[j]);  //i was thinking this would allocate space     
for(j; j < setSize; j++)
    array[j].next = array[j+1].next;
ptr = array; //i thought this would point to the beginning of the array

I have looked at a lot of sites about C and linked list. I had books but they don't give enough detail about this particular use of pointers or structures. I have been trying this for a while but I am sure I am missing something.

I just need to understand where I am going wrong and what direction to head towards.

Thanks for any and all help.

Below is a Re-post with more code:

//this should initialize array so that ptr contains all array elements
void initialize ( list array[] ) { 
int j;
for(j = 0; j < setSize - 1; j++){
array[j].next = array[j+1].next;  //using the & does not seem to work, so I don't use it
array[j].next = NULL;
}
ptr = &(array[0]);
}

Later on I am using this in my own malloc function (which is where the seg fault happens)

//this should allocate a new list cell in array
list* my_malloc () { 
list* temp; 
temp = ptr; 
if(ptr = 0) {printf("Empty!\n");  return;}
else{ //the next line creates the seg fault
ptr = (*ptr).next; 
}
return temp;
}

list* cell ( char n, list* next ) {
  list* x = my_malloc(); 
  x->value = n;
  return x;
  x->next = next;
  return x;
}

main ( void* argv, int argc ) {
  initialize(array);
  list* x = nil;
  char ch = a;
  int i;
  for ( i = 0; i < setSize; i++ )
    x = cell(ch,x); 
  for ( i = 0; i < 10; i++ ) {
    list* y = x->next;
    my_free(x);  //this is my own free function 
    x = y;
  };
  for ( i = 0; i < 10; i++ )
    x = cell(ch,x);
}

Upvotes: 0

Views: 388

Answers (4)

Carl Norum
Carl Norum

Reputation: 225052

Everything you have there is pretty close to making sense except for this line:

ptr = sizeOf(buffer[j]);

I presume you mean sizeof there? At any rate, that operation is meaningless (and illegal, since you're trying to assign an integer to a variable of pointer type). You don't need to allocate any memory, your definition of array already does that.

You do have a problem with your for loop - you're going go one past the end of the array, which might be what's causing your segmentation fault. It's either that or the fact that you didn't initialize j, so it could be accessing some memory it shouldn't. I think you probably want something like:

for (j = 0; j < setSize - 1; j++) 
{
    array[j].next = &array[j+1];
}

Edit: The reason for your segfault is that this line:

if(ptr = 0) {printf("Empty!\n");  return;}

Sets ptr to 0. I think you want a == there. Another point - you say "using the & does not seem to work, so I don't use it". That probably means your list structure is declared incorrectly, or at least in a pretty nonstandard way. You should probably show more of your program - it seems like you have some pretty fundamental misunderstandings of how pointers work.

Upvotes: 2

user497804
user497804

Reputation: 292

I think this is what you want:

#define ARRAY_LENGTH (20)

struct list
{
    char ch;
    struct list* next;
};

struct list array[ARRAY_LENGTH];   // array's memory is allocated with this, no need to use malloc
struct list* ptr = &(array[0]);    // ptr now points to the 1st item in the array
int j;                             // I'm declaring 'j' outside of the for loop just in case you are using c and not c++

for(j=0 ; j < ARRAY_LENGTH-1 ; j++)
    array[j].next = &(array[j+1]); // .next of jth item in array now points to the following item

array[j].next = NULL;              // assign .next of last item to NULL, so you know when you have reached the end of the array when traversing it.

Note that the for-loop is executed for (ARRAY_LENGTH - 1) items, not ARRAY_LENGTH items, since array[j+1] would be out of bounds in the last iteration.

Now that you have ptr pointing to the 1st item in the array, you can traverse through it with something like:

struct list* curItem;  // this will be your iterator to traverse the array
curItem = ptr;         // initialize your iterator to point to the 1st item
while(curItem != NULL) // note that with this, you don't need to know the length of the array
{
    printf("Current item's .ch is %c\r\n", curItem->ch); // don't forget to include the header for printf
    curItem = curItem->next;
}

Upvotes: 1

nmichaels
nmichaels

Reputation: 50989

sizeof doesn't allocate space. If you don't want to use malloc, you have to allocate your space either on the stack or wherever globals are stored (probably bss). Since you presumably do that with your array definition, ptr = &buffer[j] will get you a pointer to the jth element of the buffer. I think you meant "addressof" instead of "sizeof", which is spelled & in C. Of course, buffer isn't array. That's either a typo or something very wrong.

Anyway, your code is a bit misordered. What you probably wanted to do was initialize your pointer to array, then iterate through the elements, setting next:

ptr = array;
for (j = 0; j < setSize; j++)
    array[j].next = &array[j+1];
array[setSize - 1] = NULL; // The last element was set to a lie.

Upvotes: 1

BMitch
BMitch

Reputation: 264406

array[j].next = array[j+1].next;

That won't work since array[j+1].next isn't defined. Depending on how buffer[i].next is defined, you should be able to do this:

array[j].next = &array[j+1];

Upvotes: 1

Related Questions