2010-01-12 2 views
2

Что такое best Способ реализации динамически изменяющегося размера в C?Каков наилучший способ реализации динамического изменения размера в C?

Например, я хочу выделить объем памяти в стеке, но когда этот стек заполняется, память, выделенная в два раза для размещения новых данных и т.д.

Я стек реализован в минуту с помощью простой массив указателей void, таким образом я могу хранить указатели всех типов, поэтому он вполне можно использовать повторно. Когда я пытаюсь реализовать это, используя malloc()/realloc(), я запускаю ошибки при выполнении математики указателя из-за указателей void, не имеющих назначенного размера.

Что такое лучше правильно способ реализации динамически изменяемого стека в C?

EDIT:

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

#include <stdio.h> 
#include <stdlib.h> 

#include "stack.h" 

static int index = 0; 

void* CreateStack(void) 
{ 
    void *stack = malloc(INITIAL_STACK_SIZE); 
    return stack; 
} 

void* Pop(void *stack) 
{ 
    return stack + index--; 
} 

void Push(void *stack, void *value) 
{ 
    *(stack + index) = value; 
} 

void FreeStack(void *stack) 
{ 
    free(stack); 
} 
+9

Пожалуйста, разместите код. Сами указатели должны хранить фиксированный объем памяти для хранения, независимо от того, на что они указывают. –

+1

А что вы подразумеваете под «лучшим»? – 2010-01-12 23:09:14

+0

В основном два способа: 1) использовать растущий массив, 2) использовать связанный список. То, что лучше всего работает (или правильно) для вас, зависит от того, что вам нужно. – MAK

ответ

1

Один из способов - использовать массив для стека. Следите за емкостью массива. Если массив заполняется, выделите новый массив, скопируйте старые элементы в новый массив и удалите старый массив.

Другой вариант - использовать связанный список в качестве основы для стека. Это позволяет динамическое распределение для каждого нового элемента.

4

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

3

звучит, как вы делаете

malloc(n * sizeof(void)) 

прямо или косвенно, вы должны

malloc(n * sizeof(void*)) 

конечно реальный ответ станд :: стек (в C++)

+2

Nah, «реальный» ответ - java.util.Stack (на Java). Или еще лучше, список Lisp. –

+0

Настоящий ответ - практика! –

+5

C++ никогда не является реальным ответом на вопрос C, кроме как «Что вы получаете, если вы добавляете два плюсовых знака в C?» – Chuck

1

Я ответил на это раньше, в качестве подмножества предыдущего вопроса:

https://stackoverflow.com/questions/2006726/which-would-you-prefer-to-have-to-maintain/2007647#2007647

Вам нужно будет немного приспособиться, заменить char * на void *, переименовать «addString» для «push» и написать функцию «pop». О, и добавьте проверку ошибок на вызовы malloc и realloc, которые были опущены в этом ответе, потому что они были опущены в коде опроса.

Как Нил говорит, хотя «лучший» очень субъективен. Растущий массив - это только один способ реализации стека. В зависимости от шаблона использования и ваших требований к сложности кода, скорости и использования памяти вам может понадобиться связанный список, или вам может понадобиться стратегия гибридного списка/массива, аналогичная классу std::deque в C++.

0

Использовать Dave Hanson's code от C Interfaces and Implementations. Это отличная книга, и вы увидите, как сделать трюк динамического массива. Элегантный и эффективный и очень многоразовый!Код можно скачать бесплатно.