Выделение объекта фиксированного размера для указателя (указывающего на структуру) без использования malloc - PullRequest
0 голосов
/ 11 апреля 2011

У меня есть указатель на структуру list* ptr Структура содержит символ и указатель на следующую структуру, и они используются для массива структур, таких как:

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

Без использования malloc,Мне нужно инициализировать list* ptr, чтобы он содержал все элементы массива.

Я попробовал следующее, и я получил ошибку сегментации.Я считаю, что совершенно не понимаю, как работают указатели.(Я давно не трогал C)

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

Я просмотрел множество сайтов о C и связанных списках.У меня были книги, но они не дают достаточно подробностей об этом конкретном использовании указателей или структур.Я пытался это некоторое время, но я уверен, что что-то упустил.

Мне просто нужно понять, где я иду не так и в каком направлении идти.

Спасибо за любые ився помощь.

Ниже приведен повторный пост с большим кодом:

//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]);
}

Позже я использую это в своей собственной функции malloc (гдепроисходит сбой сегмента)

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

Ответы [ 4 ]

2 голосов
/ 11 апреля 2011

Все, что у вас есть, довольно близко к смыслу, кроме этой строки:

ptr = sizeOf(buffer[j]);

Полагаю, вы имеете в виду sizeof там? В любом случае, эта операция не имеет смысла (и недопустима, поскольку вы пытаетесь присвоить целое число переменной типа указателя). Вам не нужно выделять память, ваше определение array уже делает это.

У вас есть проблема с циклом for - вы пройдете один конец конца массива, что может быть причиной ошибки сегментации. Это либо тот факт, либо то, что вы не инициализировали j, поэтому он может обращаться к некоторой памяти, которой не должен. Я думаю, что вы, вероятно, хотите что-то вроде:

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

Edit: причина вашего segfault заключается в том, что эта строка:

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

Устанавливает ptr на 0. Я думаю, что вы хотите == там. Еще один момент - вы говорите: «использование &, похоже, не работает, поэтому я его не использую». Это, вероятно, означает, что ваша структура list объявлена ​​неправильно или, по крайней мере, довольно нестандартно. Вы, вероятно, должны показать больше своей программы - похоже, у вас есть довольно фундаментальное недопонимание того, как работают указатели.

1 голос
/ 11 апреля 2011

Я думаю, что это то, что вы хотите:

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

Обратите внимание, что цикл for выполняется для элементов (ARRAY_LENGTH - 1), а не элементов ARRAY_LENGTH, так как массив [j + 1] будет отсутствоватьграниц в последней итерации.

Теперь, когда у вас есть ptr, указывающий на 1-й элемент в массиве, вы можете пройти через него что-то вроде:

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;
}
1 голос
/ 11 апреля 2011
array[j].next = array[j+1].next;

Это не сработает, поскольку массив [j + 1] .next не определен. В зависимости от того, как определен buffer[i].next, вы можете сделать это:

array[j].next = &array[j+1];
1 голос
/ 11 апреля 2011

sizeof не выделяет место.Если вы не хотите использовать malloc, вы должны распределить свое пространство либо в стеке, либо там, где хранятся глобальные переменные (возможно, bss).Поскольку вы, вероятно, делаете это с помощью определения массива, ptr = &buffer[j] даст вам указатель на j-й элемент буфера.Я думаю, что вы имели в виду «addressof» вместо «sizeof», что пишется & на C. Конечно, buffer не array.Это либо опечатка, либо что-то очень неправильное.

В любом случае, ваш код немного искажен.Вероятно, вы хотели инициализировать указатель на array, а затем пройтись по элементам, установив следующее:

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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...